global: snapshot

This commit is contained in:
nym21
2026-03-04 12:36:23 +01:00
parent 0d63724903
commit 91b7f86225
115 changed files with 5342 additions and 6124 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,9 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::Indexes;
use vecdb::Exit;
use crate::{ComputeIndexes, indexes};
use crate::indexes;
use super::Vecs;
@@ -11,7 +12,7 @@ impl Vecs {
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.time

View File

@@ -1,9 +1,9 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Height, StoredU32, Timestamp};
use brk_types::{Height, Indexes, StoredU32, Timestamp};
use vecdb::{AnyVec, Cursor, EagerVec, Exit, PcoVec, ReadableVec, VecIndex};
use crate::{internal::WindowStarts, ComputeIndexes};
use crate::internal::WindowStarts;
use super::{super::time, Vecs};
@@ -12,7 +12,7 @@ impl Vecs {
&mut self,
indexer: &Indexer,
time: &time::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// Block count height + cumulative first (rolling computed after window starts)
@@ -185,7 +185,7 @@ impl Vecs {
fn compute_rolling_start<F>(
&mut self,
time: &time::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
days: usize,
get_field: F,
@@ -205,7 +205,7 @@ impl Vecs {
fn compute_rolling_start_hours<F>(
&mut self,
time: &time::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
hours: usize,
get_field: F,
@@ -225,7 +225,7 @@ impl Vecs {
fn compute_rolling_start_inner<F, D>(
&mut self,
time: &time::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
get_field: F,
expired: D,

View File

@@ -1,18 +1,18 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{StoredF64, StoredU32};
use brk_types::{Indexes, StoredF64, StoredU32};
use vecdb::Exit;
use super::super::TARGET_BLOCKS_PER_DAY_F32;
use super::Vecs;
use crate::{ComputeIndexes, indexes};
use crate::indexes;
impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// raw is fully lazy from indexer height source — no compute needed

View File

@@ -1,16 +1,16 @@
use brk_error::Result;
use brk_types::StoredU32;
use brk_types::{Indexes, StoredU32};
use vecdb::Exit;
use super::super::TARGET_BLOCKS_PER_DAY_F32;
use super::Vecs;
use crate::{ComputeIndexes, indexes};
use crate::indexes;
impl Vecs {
pub(crate) fn compute(
&mut self,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.epoch.height.compute_transform(

View File

@@ -1,17 +1,17 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{CheckedSub, Timestamp};
use brk_types::{CheckedSub, Indexes, Timestamp};
use vecdb::{Exit, ReadableVec};
use super::Vecs;
use crate::{blocks, ComputeIndexes};
use crate::blocks;
impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
count_vecs: &blocks::CountVecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let mut prev_timestamp = None;

View File

@@ -1,17 +1,17 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::StoredU64;
use brk_types::{Indexes, StoredU64};
use vecdb::Exit;
use super::Vecs;
use crate::{blocks, ComputeIndexes};
use crate::blocks;
impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
count_vecs: &blocks::CountVecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();

View File

@@ -2,12 +2,12 @@ use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{
Date, Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4,
Minute10, Minute30, Month1, Month3, Month6, Timestamp, Week1, Year1, Year10,
Indexes, Minute10, Minute30, Month1, Month3, Month6, Timestamp, Week1, Year1, Year10,
};
use derive_more::{Deref, DerefMut};
use vecdb::{EagerVec, Exit, LazyVecFrom1, PcoVec, Rw, StorageMode};
use vecdb::{EagerVec, Exit, LazyVecFrom1, PcoVec, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, indexes, internal::Indexes};
use crate::{indexes, internal::PerPeriod};
/// Timestamp and date metrics for blocks
#[derive(Traversable)]
@@ -27,7 +27,7 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(transparent)]
pub struct TimestampIndexes<M: StorageMode = Rw>(
#[allow(clippy::type_complexity)]
pub Indexes<
pub PerPeriod<
LazyVecFrom1<Minute10, Timestamp, Minute10, Height>,
LazyVecFrom1<Minute30, Timestamp, Minute30, Height>,
LazyVecFrom1<Hour1, Timestamp, Hour1, Height>,
@@ -53,17 +53,18 @@ impl TimestampIndexes {
&mut self,
indexer: &brk_indexer::Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let prev_height = starting_indexes.height.decremented().unwrap_or_default();
self.halvingepoch.compute_indirect_sequential(
starting_indexes.halvingepoch,
indexes.height.halvingepoch.collect_one(prev_height).unwrap_or_default(),
&indexes.halvingepoch.first_height,
&indexer.vecs.blocks.timestamp,
exit,
)?;
self.difficultyepoch.compute_indirect_sequential(
starting_indexes.difficultyepoch,
indexes.height.difficultyepoch.collect_one(prev_height).unwrap_or_default(),
&indexes.difficultyepoch.first_height,
&indexer.vecs.blocks.timestamp,
exit,

View File

@@ -1,17 +1,17 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::BasisPoints16;
use brk_types::{BasisPoints16, Indexes};
use vecdb::Exit;
use super::Vecs;
use crate::{blocks, ComputeIndexes};
use crate::blocks;
impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
count_vecs: &blocks::CountVecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();

View File

@@ -1,14 +1,14 @@
use brk_error::Result;
use brk_types::{Bitcoin, CheckedSub, StoredF64};
use brk_types::{Bitcoin, CheckedSub, Indexes, StoredF64};
use vecdb::Exit;
use super::Vecs;
use crate::{ComputeIndexes, blocks, distribution};
use crate::{blocks, distribution};
impl Vecs {
pub(crate) fn compute(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
blocks: &blocks::Vecs,
distribution: &distribution::Vecs,
exit: &Exit,

View File

@@ -1,15 +1,15 @@
use brk_error::Result;
use brk_types::BasisPointsSigned32;
use brk_types::{BasisPointsSigned32, Indexes};
use vecdb::Exit;
use super::super::activity;
use super::Vecs;
use crate::{ComputeIndexes, supply};
use crate::supply;
impl Vecs {
pub(crate) fn compute(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
supply: &supply::Vecs,
activity: &activity::Vecs,
exit: &Exit,

View File

@@ -1,16 +1,16 @@
use brk_error::Result;
use brk_types::Cents;
use brk_types::{Cents, Indexes};
use vecdb::Exit;
use super::super::{activity, value};
use super::Vecs;
use crate::{ComputeIndexes, distribution, mining};
use crate::{distribution, mining};
impl Vecs {
#[allow(clippy::too_many_arguments)]
pub(crate) fn compute(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
mining: &mining::Vecs,
distribution: &distribution::Vecs,
activity: &activity::Vecs,

View File

@@ -1,14 +1,15 @@
use brk_error::Result;
use brk_types::Indexes;
use vecdb::Exit;
use super::Vecs;
use crate::{ComputeIndexes, blocks, distribution, mining, prices, supply};
use crate::{blocks, distribution, mining, prices, supply};
impl Vecs {
#[allow(clippy::too_many_arguments)]
pub(crate) fn compute(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
prices: &prices::Vecs,
blocks: &blocks::Vecs,
mining: &mining::Vecs,

View File

@@ -1,16 +1,16 @@
use brk_error::Result;
use brk_types::Cents;
use brk_types::{Cents, Indexes};
use vecdb::Exit;
use super::super::{activity, cap, supply};
use super::Vecs;
use crate::{ComputeIndexes, blocks, distribution, prices};
use crate::{blocks, distribution, prices};
impl Vecs {
#[allow(clippy::too_many_arguments)]
pub(crate) fn compute(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
prices: &prices::Vecs,
blocks: &blocks::Vecs,
distribution: &distribution::Vecs,

View File

@@ -1,14 +1,14 @@
use brk_error::Result;
use brk_types::StoredF64;
use brk_types::{Indexes, StoredF64};
use vecdb::Exit;
use super::{super::value, Vecs};
use crate::{blocks, ComputeIndexes, prices, traits::ComputeRollingMedianFromStarts};
use crate::{blocks, prices, traits::ComputeRollingMedianFromStarts};
impl Vecs {
pub(crate) fn compute(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
value: &value::Vecs,

View File

@@ -1,14 +1,15 @@
use brk_error::Result;
use brk_types::Indexes;
use vecdb::Exit;
use super::super::activity;
use super::Vecs;
use crate::{ComputeIndexes, distribution};
use crate::distribution;
impl Vecs {
pub(crate) fn compute(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
distribution: &distribution::Vecs,
activity: &activity::Vecs,
exit: &Exit,

View File

@@ -1,15 +1,15 @@
use brk_error::Result;
use brk_types::{Bitcoin, Dollars, StoredF64};
use brk_types::{Bitcoin, Dollars, Indexes, StoredF64};
use vecdb::Exit;
use super::super::activity;
use super::Vecs;
use crate::{ComputeIndexes, blocks, distribution, prices};
use crate::{blocks, distribution, prices};
impl Vecs {
pub(crate) fn compute(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
prices: &prices::Vecs,
blocks: &blocks::Vecs,
distribution: &distribution::Vecs,

View File

@@ -233,18 +233,8 @@ impl AddressTypeToActivityCountVecs {
}
pub(crate) fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
let inner = &mut self.0;
let mut vecs: Vec<&mut dyn AnyStoredVec> = Vec::new();
for type_vecs in [
&mut inner.p2pk65,
&mut inner.p2pk33,
&mut inner.p2pkh,
&mut inner.p2sh,
&mut inner.p2wpkh,
&mut inner.p2wsh,
&mut inner.p2tr,
&mut inner.p2a,
] {
for type_vecs in self.0.values_mut() {
vecs.push(&mut type_vecs.reactivated.height);
vecs.push(&mut type_vecs.sending.height);
vecs.push(&mut type_vecs.receiving.height);
@@ -256,14 +246,9 @@ impl AddressTypeToActivityCountVecs {
}
pub(crate) fn reset_height(&mut self) -> Result<()> {
self.p2pk65.reset_height()?;
self.p2pk33.reset_height()?;
self.p2pkh.reset_height()?;
self.p2sh.reset_height()?;
self.p2wpkh.reset_height()?;
self.p2wsh.reset_height()?;
self.p2tr.reset_height()?;
self.p2a.reset_height()?;
for v in self.0.values_mut() {
v.reset_height()?;
}
Ok(())
}
@@ -284,19 +269,9 @@ impl AddressTypeToActivityCountVecs {
height: Height,
counts: &AddressTypeToActivityCounts,
) -> Result<()> {
self.p2pk65
.truncate_push_height(height, &counts.p2pk65)?;
self.p2pk33
.truncate_push_height(height, &counts.p2pk33)?;
self.p2pkh
.truncate_push_height(height, &counts.p2pkh)?;
self.p2sh.truncate_push_height(height, &counts.p2sh)?;
self.p2wpkh
.truncate_push_height(height, &counts.p2wpkh)?;
self.p2wsh
.truncate_push_height(height, &counts.p2wsh)?;
self.p2tr.truncate_push_height(height, &counts.p2tr)?;
self.p2a.truncate_push_height(height, &counts.p2a)?;
for (vecs, c) in self.0.values_mut().zip(counts.0.values()) {
vecs.truncate_push_height(height, c)?;
}
Ok(())
}

View File

@@ -1,7 +1,7 @@
use brk_cohort::ByAddressType;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, StoredF64, StoredU64, Version};
use brk_types::{Height, Indexes, StoredF64, StoredU64, Version};
use derive_more::{Deref, DerefMut};
use rayon::prelude::*;
use vecdb::{
@@ -9,7 +9,7 @@ use vecdb::{
WritableVec,
};
use crate::{ComputeIndexes, blocks, indexes, internal::ComputedFromHeight};
use crate::{blocks, indexes, internal::ComputedFromHeight};
/// Address count with 1m change metric for a single type.
#[derive(Traversable)]
@@ -40,7 +40,7 @@ impl AddrCountVecs {
pub(crate) fn compute_rest(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.change_1m.height.compute_rolling_change(
@@ -116,32 +116,11 @@ impl AddressTypeToAddrCountVecs {
}
pub(crate) fn min_stateful_height(&self) -> usize {
self.p2pk65
.count
.height
.len()
.min(self.p2pk33.count.height.len())
.min(self.p2pkh.count.height.len())
.min(self.p2sh.count.height.len())
.min(self.p2wpkh.count.height.len())
.min(self.p2wsh.count.height.len())
.min(self.p2tr.count.height.len())
.min(self.p2a.count.height.len())
self.0.values().map(|v| v.count.height.len()).min().unwrap()
}
pub(crate) fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
let inner = &mut self.0;
[
&mut inner.p2pk65.count.height as &mut dyn AnyStoredVec,
&mut inner.p2pk33.count.height as &mut dyn AnyStoredVec,
&mut inner.p2pkh.count.height as &mut dyn AnyStoredVec,
&mut inner.p2sh.count.height as &mut dyn AnyStoredVec,
&mut inner.p2wpkh.count.height as &mut dyn AnyStoredVec,
&mut inner.p2wsh.count.height as &mut dyn AnyStoredVec,
&mut inner.p2tr.count.height as &mut dyn AnyStoredVec,
&mut inner.p2a.count.height as &mut dyn AnyStoredVec,
]
.into_par_iter()
self.0.par_values_mut().map(|v| &mut v.count.height as &mut dyn AnyStoredVec)
}
pub(crate) fn truncate_push_height(
@@ -149,82 +128,34 @@ impl AddressTypeToAddrCountVecs {
height: Height,
addr_counts: &AddressTypeToAddressCount,
) -> Result<()> {
self.p2pk65
.count
.height
.truncate_push(height, addr_counts.p2pk65.into())?;
self.p2pk33
.count
.height
.truncate_push(height, addr_counts.p2pk33.into())?;
self.p2pkh
.count
.height
.truncate_push(height, addr_counts.p2pkh.into())?;
self.p2sh
.count
.height
.truncate_push(height, addr_counts.p2sh.into())?;
self.p2wpkh
.count
.height
.truncate_push(height, addr_counts.p2wpkh.into())?;
self.p2wsh
.count
.height
.truncate_push(height, addr_counts.p2wsh.into())?;
self.p2tr
.count
.height
.truncate_push(height, addr_counts.p2tr.into())?;
self.p2a
.count
.height
.truncate_push(height, addr_counts.p2a.into())?;
for (vecs, &count) in self.0.values_mut().zip(addr_counts.values()) {
vecs.count.height.truncate_push(height, count.into())?;
}
Ok(())
}
pub(crate) fn reset_height(&mut self) -> Result<()> {
use vecdb::WritableVec;
self.p2pk65.count.height.reset()?;
self.p2pk33.count.height.reset()?;
self.p2pkh.count.height.reset()?;
self.p2sh.count.height.reset()?;
self.p2wpkh.count.height.reset()?;
self.p2wsh.count.height.reset()?;
self.p2tr.count.height.reset()?;
self.p2a.count.height.reset()?;
for v in self.0.values_mut() {
v.count.height.reset()?;
}
Ok(())
}
pub(crate) fn compute_rest(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.p2pk65.compute_rest(blocks, starting_indexes, exit)?;
self.p2pk33.compute_rest(blocks, starting_indexes, exit)?;
self.p2pkh.compute_rest(blocks, starting_indexes, exit)?;
self.p2sh.compute_rest(blocks, starting_indexes, exit)?;
self.p2wpkh.compute_rest(blocks, starting_indexes, exit)?;
self.p2wsh.compute_rest(blocks, starting_indexes, exit)?;
self.p2tr.compute_rest(blocks, starting_indexes, exit)?;
self.p2a.compute_rest(blocks, starting_indexes, exit)?;
for v in self.0.values_mut() {
v.compute_rest(blocks, starting_indexes, exit)?;
}
Ok(())
}
pub(crate) fn by_height(&self) -> Vec<&EagerVec<PcoVec<Height, StoredU64>>> {
vec![
&self.p2pk65.count.height,
&self.p2pk33.count.height,
&self.p2pkh.count.height,
&self.p2sh.count.height,
&self.p2wpkh.count.height,
&self.p2wsh.count.height,
&self.p2tr.count.height,
&self.p2a.count.height,
]
self.0.values().map(|v| &v.count.height).collect()
}
}
@@ -278,7 +209,7 @@ impl AddrCountsVecs {
pub(crate) fn compute_rest(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.by_addresstype

View File

@@ -53,11 +53,10 @@ impl TotalAddrCountVecs {
empty_addr_count: &AddrCountsVecs,
exit: &Exit,
) -> Result<()> {
self.all.height.compute_transform2(
self.all.height.compute_add(
max_from,
&addr_count.all.count.height,
&empty_addr_count.all.count.height,
|(h, a, b, ..)| (h, StoredU64::from(*a + *b)),
exit,
)?;
@@ -71,11 +70,10 @@ impl TotalAddrCountVecs {
.zip(empty_addr_count.by_addresstype.iter()),
)
{
total.height.compute_transform2(
total.height.compute_add(
max_from,
&addr.count.height,
&empty.count.height,
|(h, a, b, ..)| (h, StoredU64::from(*a + *b)),
exit,
)?;
}

View File

@@ -5,12 +5,12 @@ use brk_cohort::{
};
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Dollars, Height, Sats, Version};
use brk_types::{Dollars, Height, Indexes, Sats, Version};
use derive_more::{Deref, DerefMut};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, distribution::DynCohortVecs, indexes, prices};
use crate::{blocks, distribution::DynCohortVecs, indexes, prices};
use crate::distribution::metrics::CohortMetricsBase;
@@ -83,7 +83,7 @@ impl AddressCohorts {
/// Compute overlapping cohorts from component amount_range cohorts.
pub(crate) fn compute_overlapping_vecs(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.for_each_aggregate(|vecs, sources| {
@@ -96,7 +96,7 @@ impl AddressCohorts {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// 1. Compute addr_count_change_1m using rolling window
@@ -134,7 +134,7 @@ impl AddressCohorts {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &HM,
all_supply_sats: &AS,
exit: &Exit,

View File

@@ -3,12 +3,12 @@ use std::path::Path;
use brk_cohort::{CohortContext, Filter, Filtered};
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Dollars, Height, Sats, StoredF64, StoredU64, Version};
use brk_types::{Cents, Dollars, Height, Indexes, Sats, StoredF64, StoredU64, Version};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, AnyVec, Database, Exit, WritableVec, ReadableVec, Rw, StorageMode};
use crate::{
ComputeIndexes, blocks,
blocks,
distribution::state::AddressCohortState,
indexes,
internal::ComputedFromHeight,
@@ -53,7 +53,7 @@ impl AddressCohortVecs {
let cfg = ImportConfig {
db,
filter,
filter: &filter,
full_name: &full_name,
version,
indexes,
@@ -211,7 +211,7 @@ impl DynCohortVecs for AddressCohortVecs {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.metrics
@@ -221,7 +221,7 @@ impl DynCohortVecs for AddressCohortVecs {
fn compute_net_sentiment_height(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.metrics
@@ -252,7 +252,7 @@ impl DynCohortVecs for AddressCohortVecs {
impl CohortVecs for AddressCohortVecs {
fn compute_from_stateful(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {
@@ -277,7 +277,7 @@ impl CohortVecs for AddressCohortVecs {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
all_supply_sats: &impl ReadableVec<Height, Sats>,
exit: &Exit,

View File

@@ -1,8 +1,8 @@
use brk_error::Result;
use brk_types::{Cents, Dollars, Height, Sats, Version};
use brk_types::{Cents, Dollars, Height, Indexes, Sats, Version};
use vecdb::{Exit, ReadableVec};
use crate::{ComputeIndexes, blocks, prices};
use crate::{blocks, prices};
/// Dynamic dispatch trait for cohort vectors.
///
@@ -35,14 +35,14 @@ pub trait DynCohortVecs: Send + Sync {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()>;
/// Compute net_sentiment.height for separate cohorts (greed - pain).
fn compute_net_sentiment_height(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()>;
@@ -63,7 +63,7 @@ pub trait CohortVecs: DynCohortVecs {
/// Compute aggregate cohort from component cohorts.
fn compute_from_stateful(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()>;
@@ -73,7 +73,7 @@ pub trait CohortVecs: DynCohortVecs {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
all_supply_sats: &impl ReadableVec<Height, Sats>,
exit: &Exit,

View File

@@ -7,14 +7,14 @@ use brk_cohort::{
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{
BasisPoints16, Cents, CentsCompact, CostBasisDistribution, Date, Dollars, Height, Sats,
Version,
BasisPoints16, Cents, CentsCompact, CostBasisDistribution, Date, Dollars, Height, Indexes,
Sats, Version,
};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, Database, Exit, ReadOnlyClone, ReadableVec, Rw, StorageMode, WritableVec};
use crate::{
ComputeIndexes, blocks,
blocks,
distribution::DynCohortVecs,
indexes,
internal::{PERCENTILES, PERCENTILES_LEN, compute_spot_percentile_rank},
@@ -76,7 +76,7 @@ impl UTXOCohorts<Rw> {
let all_full_name = CohortContext::Utxo.full_name(&Filter::All, "");
let all_cfg = ImportConfig {
db,
filter: Filter::All,
filter: &Filter::All,
full_name: &all_full_name,
version: v + Version::ONE,
indexes,
@@ -91,7 +91,7 @@ impl UTXOCohorts<Rw> {
let full_name = CohortContext::Utxo.full_name(&f, name);
let cfg = ImportConfig {
db,
filter: f,
filter: &f,
full_name: &full_name,
version: v,
indexes,
@@ -110,7 +110,7 @@ impl UTXOCohorts<Rw> {
let full_name = CohortContext::Utxo.full_name(&f, name);
let cfg = ImportConfig {
db,
filter: f,
filter: &f,
full_name: &full_name,
version: v,
indexes,
@@ -141,7 +141,7 @@ impl UTXOCohorts<Rw> {
let full_name = CohortContext::Utxo.full_name(&f, "sth");
let cfg = ImportConfig {
db,
filter: f,
filter: &f,
full_name: &full_name,
version: v,
indexes,
@@ -160,7 +160,7 @@ impl UTXOCohorts<Rw> {
let full_name = CohortContext::Utxo.full_name(&f, "lth");
let cfg = ImportConfig {
db,
filter: f,
filter: &f,
full_name: &full_name,
version: v,
indexes,
@@ -177,7 +177,7 @@ impl UTXOCohorts<Rw> {
let full_name = CohortContext::Utxo.full_name(&f, name);
let cfg = ImportConfig {
db,
filter: f,
filter: &f,
full_name: &full_name,
version: v,
indexes,
@@ -195,7 +195,7 @@ impl UTXOCohorts<Rw> {
let full_name = CohortContext::Utxo.full_name(&f, name);
let cfg = ImportConfig {
db,
filter: f,
filter: &f,
full_name: &full_name,
version: v,
indexes,
@@ -213,7 +213,7 @@ impl UTXOCohorts<Rw> {
let full_name = CohortContext::Utxo.full_name(&f, name);
let cfg = ImportConfig {
db,
filter: f,
filter: &f,
full_name: &full_name,
version: v,
indexes,
@@ -301,7 +301,7 @@ impl UTXOCohorts<Rw> {
/// Compute overlapping cohorts from component age/amount range cohorts.
pub(crate) fn compute_overlapping_vecs(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let age_range = &self.age_range;
@@ -423,7 +423,7 @@ impl UTXOCohorts<Rw> {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// 1. Compute all metrics except net_sentiment (all cohorts via DynCohortVecs)
@@ -565,7 +565,7 @@ impl UTXOCohorts<Rw> {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &HM,
exit: &Exit,
) -> Result<()>

View File

@@ -1,10 +1,10 @@
use brk_cohort::{Filter, Filtered};
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, Version};
use brk_types::{Cents, Height, Indexes, Version};
use vecdb::{Exit, ReadableVec};
use crate::{ComputeIndexes, blocks, distribution::state::UTXOCohortState, prices};
use crate::{blocks, distribution::state::UTXOCohortState, prices};
use crate::distribution::metrics::CohortMetricsBase;
@@ -127,7 +127,7 @@ impl<Metrics: CohortMetricsBase + Traversable> DynCohortVecs for UTXOCohortVecs<
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.metrics
@@ -136,7 +136,7 @@ impl<Metrics: CohortMetricsBase + Traversable> DynCohortVecs for UTXOCohortVecs<
fn compute_net_sentiment_height(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.metrics

View File

@@ -1,9 +1,9 @@
use brk_error::Result;
use brk_types::{Dollars, Height};
use brk_types::{Dollars, Height, Indexes};
use tracing::info;
use vecdb::{Exit, ReadableVec};
use crate::{ComputeIndexes, blocks, prices};
use crate::{blocks, prices};
use super::super::cohorts::{AddressCohorts, UTXOCohorts};
@@ -15,7 +15,7 @@ use super::super::cohorts::{AddressCohorts, UTXOCohorts};
pub(crate) fn compute_overlapping(
utxo_cohorts: &mut UTXOCohorts,
address_cohorts: &mut AddressCohorts,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
info!("Computing overlapping cohorts...");
@@ -34,7 +34,7 @@ pub(crate) fn compute_rest_part1(
address_cohorts: &mut AddressCohorts,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
info!("Computing rest part 1...");
@@ -53,7 +53,7 @@ pub(crate) fn compute_rest_part2<HM>(
address_cohorts: &mut AddressCohorts,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &HM,
exit: &Exit,
) -> Result<()>

View File

@@ -1,11 +1,11 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Height, Sats, StoredF64, Version};
use brk_types::{Bitcoin, Height, Indexes, Sats, StoredF64, Version};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, AnyVec, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode, WritableVec};
use crate::{
ComputeIndexes, blocks,
blocks,
internal::{ComputedFromHeightCumulativeSum, RollingEmas2w, ValueFromHeightCumulative},
};
@@ -37,45 +37,22 @@ impl ActivityMetrics {
/// Import activity metrics from database.
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
Ok(Self {
sent: ValueFromHeightCumulative::forced_import(
cfg.db,
&cfg.name("sent"),
cfg.version,
cfg.indexes,
)?,
sent_ema: RollingEmas2w::forced_import(
cfg.db,
&cfg.name("sent"),
cfg.version,
cfg.indexes,
)?,
sent: cfg.import_value_cumulative("sent", Version::ZERO)?,
sent_ema: cfg.import_emas_2w("sent", Version::ZERO)?,
satblocks_destroyed: EagerVec::forced_import(
cfg.db,
&cfg.name("satblocks_destroyed"),
cfg.version,
)?,
satdays_destroyed: EagerVec::forced_import(
cfg.db,
&cfg.name("satdays_destroyed"),
cfg.version,
)?,
coinblocks_destroyed: ComputedFromHeightCumulativeSum::forced_import(
cfg.db,
&cfg.name("coinblocks_destroyed"),
cfg.version,
cfg.indexes,
)?,
coindays_destroyed: ComputedFromHeightCumulativeSum::forced_import(
cfg.db,
&cfg.name("coindays_destroyed"),
cfg.version,
cfg.indexes,
)?,
coinblocks_destroyed: cfg.import_cumulative_sum("coinblocks_destroyed", Version::ZERO)?,
coindays_destroyed: cfg.import_cumulative_sum("coindays_destroyed", Version::ZERO)?,
})
}
@@ -125,7 +102,7 @@ impl ActivityMetrics {
/// Compute aggregate values from separate cohorts.
pub(crate) fn compute_from_stateful(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {
@@ -160,7 +137,7 @@ impl ActivityMetrics {
pub(crate) fn compute_rest_part1(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = blocks.count.window_starts();

View File

@@ -1,11 +1,11 @@
use brk_cohort::Filter;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Dollars, Height, Sats, Version};
use brk_types::{Cents, Dollars, Height, Indexes, Sats, Version};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, distribution::state::CohortState, prices};
use crate::{blocks, distribution::state::CohortState, prices};
use crate::distribution::metrics::{
ActivityMetrics, CohortMetricsBase, CostBasisBase, ImportConfig, OutputsMetrics, RealizedBase,
@@ -95,7 +95,7 @@ impl AdjustedCohortMetrics {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
up_to_1h_value_created: &impl ReadableVec<Height, Cents>,
up_to_1h_value_destroyed: &impl ReadableVec<Height, Cents>,

View File

@@ -1,11 +1,11 @@
use brk_cohort::Filter;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Dollars, Height, Version};
use brk_types::{Cents, Dollars, Height, Indexes, Version};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, distribution::state::CohortState, prices};
use crate::{blocks, distribution::state::CohortState, prices};
use crate::distribution::metrics::{
ActivityMetrics, CohortMetricsBase, CostBasisBase, CostBasisWithExtended, ImportConfig,
@@ -135,7 +135,7 @@ impl AllCohortMetrics {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
up_to_1h_value_created: &impl ReadableVec<Height, Cents>,
up_to_1h_value_destroyed: &impl ReadableVec<Height, Cents>,

View File

@@ -1,11 +1,11 @@
use brk_cohort::Filter;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Dollars, Height, Sats, Version};
use brk_types::{Cents, Dollars, Height, Indexes, Sats, Version};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, distribution::state::CohortState, prices};
use crate::{blocks, distribution::state::CohortState, prices};
use crate::distribution::metrics::{
ActivityMetrics, CohortMetricsBase, CostBasisBase, ImportConfig, OutputsMetrics,
@@ -97,7 +97,7 @@ impl BasicCohortMetrics {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
all_supply_sats: &impl ReadableVec<Height, Sats>,
exit: &Exit,
@@ -126,7 +126,7 @@ impl BasicCohortMetrics {
pub(crate) fn compute_from_stateful(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {

View File

@@ -1,11 +1,11 @@
use brk_cohort::Filter;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Dollars, Height, Sats, Version};
use brk_types::{Cents, Dollars, Height, Indexes, Sats, Version};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, distribution::state::CohortState, prices};
use crate::{blocks, distribution::state::CohortState, prices};
use crate::distribution::metrics::{
ActivityMetrics, CohortMetricsBase, CostBasisBase, CostBasisWithExtended, ImportConfig,
@@ -98,7 +98,7 @@ impl ExtendedCohortMetrics {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
all_supply_sats: &impl ReadableVec<Height, Sats>,
exit: &Exit,

View File

@@ -1,11 +1,11 @@
use brk_cohort::Filter;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Dollars, Height, Sats, Version};
use brk_types::{Cents, Dollars, Height, Indexes, Sats, Version};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, distribution::state::CohortState, prices};
use crate::{blocks, distribution::state::CohortState, prices};
use crate::distribution::metrics::{
ActivityMetrics, CohortMetricsBase, CostBasisBase, CostBasisWithExtended, ImportConfig,
@@ -98,7 +98,7 @@ impl ExtendedAdjustedCohortMetrics {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
up_to_1h_value_created: &impl ReadableVec<Height, Cents>,
up_to_1h_value_destroyed: &impl ReadableVec<Height, Cents>,

View File

@@ -1,13 +1,24 @@
use brk_cohort::Filter;
use brk_types::Version;
use vecdb::Database;
use brk_error::Result;
use brk_types::{BasisPoints16, BasisPointsSigned16, Cents, Height, Version};
use schemars::JsonSchema;
use vecdb::{BytesVec, BytesVecValue, Database, ImportableVec};
use crate::indexes;
use crate::{
indexes,
internal::{
CentsType, ComputedFromHeight, ComputedFromHeightCumulative, ComputedFromHeightCumulativeSum,
ComputedFromHeightRatio, FiatFromHeight, NumericValue, PercentFromHeight,
PercentRollingEmas1w1m, PercentRollingWindows, Price, RollingEmas1w1m, RollingEmas2w,
RollingWindows, ValueFromHeight, ValueFromHeightChange, ValueFromHeightCumulative,
},
};
/// Configuration for importing metrics.
#[derive(Clone, Copy)]
pub struct ImportConfig<'a> {
pub db: &'a Database,
pub filter: Filter,
pub filter: &'a Filter,
pub full_name: &'a str,
pub version: Version,
pub indexes: &'a indexes::Vecs,
@@ -25,4 +36,103 @@ impl<'a> ImportConfig<'a> {
}
}
// --- Computed types ---
pub(crate) fn import_computed<T: NumericValue + JsonSchema>(
&self,
suffix: &str,
offset: Version,
) -> Result<ComputedFromHeight<T>> {
ComputedFromHeight::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_cumulative<T: NumericValue + JsonSchema>(
&self,
suffix: &str,
offset: Version,
) -> Result<ComputedFromHeightCumulative<T>> {
ComputedFromHeightCumulative::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_cumulative_sum<T: NumericValue + JsonSchema>(
&self,
suffix: &str,
offset: Version,
) -> Result<ComputedFromHeightCumulativeSum<T>> {
ComputedFromHeightCumulativeSum::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
// --- Percent types ---
pub(crate) fn import_percent_bp16(
&self,
suffix: &str,
offset: Version,
) -> Result<PercentFromHeight<BasisPoints16>> {
PercentFromHeight::forced_import_bp16(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_percent_bps16(
&self,
suffix: &str,
offset: Version,
) -> Result<PercentFromHeight<BasisPointsSigned16>> {
PercentFromHeight::forced_import_bps16(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
// --- Value types ---
pub(crate) fn import_fiat<C: CentsType>(&self, suffix: &str, offset: Version) -> Result<FiatFromHeight<C>> {
FiatFromHeight::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_value(&self, suffix: &str, offset: Version) -> Result<ValueFromHeight> {
ValueFromHeight::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_value_cumulative(&self, suffix: &str, offset: Version) -> Result<ValueFromHeightCumulative> {
ValueFromHeightCumulative::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_value_change(&self, suffix: &str, offset: Version) -> Result<ValueFromHeightChange> {
ValueFromHeightChange::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
// --- Price and ratio ---
pub(crate) fn import_price(&self, suffix: &str, offset: Version) -> Result<Price<ComputedFromHeight<Cents>>> {
Price::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_ratio(&self, suffix: &str, offset: Version) -> Result<ComputedFromHeightRatio> {
ComputedFromHeightRatio::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
// --- Bytes ---
pub(crate) fn import_bytes<T: BytesVecValue>(&self, suffix: &str, offset: Version) -> Result<BytesVec<Height, T>> {
Ok(BytesVec::forced_import(self.db, &self.name(suffix), self.version + offset)?)
}
// --- Rolling ---
pub(crate) fn import_rolling<T: NumericValue + JsonSchema>(&self, suffix: &str, offset: Version) -> Result<RollingWindows<T>> {
RollingWindows::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_percent_rolling_bp16(&self, suffix: &str, offset: Version) -> Result<PercentRollingWindows<BasisPoints16>> {
PercentRollingWindows::forced_import_bp16(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_emas_1w_1m<T: NumericValue + JsonSchema>(&self, suffix: &str, offset: Version) -> Result<RollingEmas1w1m<T>> {
RollingEmas1w1m::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_percent_emas_1w_1m_bp16(&self, suffix: &str, offset: Version) -> Result<PercentRollingEmas1w1m<BasisPoints16>> {
PercentRollingEmas1w1m::forced_import_bp16(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
pub(crate) fn import_emas_2w(&self, suffix: &str, offset: Version) -> Result<RollingEmas2w> {
RollingEmas2w::forced_import(self.db, &self.name(suffix), self.version + offset, self.indexes)
}
}

View File

@@ -1,10 +1,9 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height};
use brk_types::{Cents, Height, Indexes, Version};
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::{
ComputeIndexes,
distribution::state::CohortState,
internal::{ComputedFromHeight, Price},
};
@@ -24,18 +23,8 @@ pub struct CostBasisBase<M: StorageMode = Rw> {
impl CostBasisBase {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
Ok(Self {
min: Price::forced_import(
cfg.db,
&cfg.name("cost_basis_min"),
cfg.version,
cfg.indexes,
)?,
max: Price::forced_import(
cfg.db,
&cfg.name("cost_basis_max"),
cfg.version,
cfg.indexes,
)?,
min: cfg.import_price("cost_basis_min", Version::ZERO)?,
max: cfg.import_price("cost_basis_max", Version::ZERO)?,
})
}
@@ -74,7 +63,7 @@ impl CostBasisBase {
pub(crate) fn compute_from_stateful(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {

View File

@@ -44,18 +44,8 @@ impl CostBasisExtended {
cfg.version,
cfg.indexes,
)?,
spot_cost_basis_percentile: PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("spot_cost_basis_percentile"),
cfg.version,
cfg.indexes,
)?,
spot_invested_capital_percentile: PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("spot_invested_capital_percentile"),
cfg.version,
cfg.indexes,
)?,
spot_cost_basis_percentile: cfg.import_percent_bp16("spot_cost_basis_percentile", Version::ZERO)?,
spot_invested_capital_percentile: cfg.import_percent_bp16("spot_invested_capital_percentile", Version::ZERO)?,
})
}

View File

@@ -20,10 +20,10 @@ pub use unrealized::*;
use brk_cohort::Filter;
use brk_error::Result;
use brk_types::{Cents, Height, Version};
use brk_types::{Cents, Height, Indexes, Version};
use vecdb::{AnyStoredVec, Exit};
use crate::{ComputeIndexes, blocks, distribution::state::CohortState, prices};
use crate::{blocks, distribution::state::CohortState, prices};
/// Trait defining the interface for cohort metrics containers.
///
@@ -96,7 +96,7 @@ pub trait CohortMetricsBase: Send + Sync {
/// Compute net_sentiment.height as capital-weighted average of component cohorts (same type).
fn compute_net_sentiment_from_others(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()>
@@ -124,7 +124,7 @@ pub trait CohortMetricsBase: Send + Sync {
/// Compute net_sentiment.height as capital-weighted average from heterogeneous sources.
fn compute_net_sentiment_from_others_dyn(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&dyn CohortMetricsBase],
exit: &Exit,
) -> Result<()> {
@@ -151,7 +151,7 @@ pub trait CohortMetricsBase: Send + Sync {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.supply_mut()
@@ -184,7 +184,7 @@ pub trait CohortMetricsBase: Send + Sync {
/// Compute net_sentiment.height for separate cohorts (greed - pain).
fn compute_net_sentiment_height(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.unrealized_base_mut()
@@ -196,7 +196,7 @@ pub trait CohortMetricsBase: Send + Sync {
/// Uses only base fields (supply, outputs, activity, realized_base, unrealized_base, cost_basis_base).
fn compute_base_from_others(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&dyn CohortMetricsBase],
exit: &Exit,
) -> Result<()>

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, StoredF64, StoredU64};
use brk_types::{Height, Indexes, StoredF64, StoredU64, Version};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::{ComputeIndexes, blocks, internal::ComputedFromHeight};
use crate::{blocks, internal::ComputedFromHeight};
use super::ImportConfig;
@@ -19,18 +19,8 @@ impl OutputsMetrics {
/// Import output metrics from database.
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
Ok(Self {
utxo_count: ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("utxo_count"),
cfg.version,
cfg.indexes,
)?,
utxo_count_change_1m: ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("utxo_count_change_1m"),
cfg.version,
cfg.indexes,
)?,
utxo_count: cfg.import_computed("utxo_count", Version::ZERO)?,
utxo_count_change_1m: cfg.import_computed("utxo_count_change_1m", Version::ZERO)?,
})
}
@@ -55,7 +45,7 @@ impl OutputsMetrics {
/// Compute aggregate values from separate cohorts.
pub(crate) fn compute_from_stateful(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {
@@ -74,7 +64,7 @@ impl OutputsMetrics {
pub(crate) fn compute_rest(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.utxo_count_change_1m.height.compute_rolling_change(

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, StoredF64, Version};
use brk_types::{Cents, Height, Indexes, StoredF64, Version};
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::{
ComputeIndexes, blocks,
blocks,
internal::{ComputedFromHeight, RatioCents64, RollingEmas1w1m, RollingWindows},
};
@@ -28,41 +28,13 @@ pub struct RealizedAdjusted<M: StorageMode = Rw> {
impl RealizedAdjusted {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v1 = Version::ONE;
let adjusted_value_created = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("adjusted_value_created"),
cfg.version,
cfg.indexes,
)?;
let adjusted_value_destroyed = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("adjusted_value_destroyed"),
cfg.version,
cfg.indexes,
)?;
let adjusted_value_created_sum = RollingWindows::forced_import(
cfg.db, &cfg.name("adjusted_value_created"), cfg.version + v1, cfg.indexes,
)?;
let adjusted_value_destroyed_sum = RollingWindows::forced_import(
cfg.db, &cfg.name("adjusted_value_destroyed"), cfg.version + v1, cfg.indexes,
)?;
let adjusted_sopr = RollingWindows::forced_import(
cfg.db, &cfg.name("adjusted_sopr"), cfg.version + v1, cfg.indexes,
)?;
let adjusted_sopr_ema = RollingEmas1w1m::forced_import(
cfg.db, &cfg.name("adjusted_sopr_24h"), cfg.version + v1, cfg.indexes,
)?;
Ok(RealizedAdjusted {
adjusted_value_created,
adjusted_value_destroyed,
adjusted_value_created_sum,
adjusted_value_destroyed_sum,
adjusted_sopr,
adjusted_sopr_ema,
adjusted_value_created: cfg.import_computed("adjusted_value_created", Version::ZERO)?,
adjusted_value_destroyed: cfg.import_computed("adjusted_value_destroyed", Version::ZERO)?,
adjusted_value_created_sum: cfg.import_rolling("adjusted_value_created", Version::ONE)?,
adjusted_value_destroyed_sum: cfg.import_rolling("adjusted_value_destroyed", Version::ONE)?,
adjusted_sopr: cfg.import_rolling("adjusted_sopr", Version::ONE)?,
adjusted_sopr_ema: cfg.import_emas_1w_1m("adjusted_sopr_24h", Version::ONE)?,
})
}
@@ -70,7 +42,7 @@ impl RealizedAdjusted {
pub(crate) fn compute_rest_part2_adj(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
base_value_created: &impl ReadableVec<Height, Cents>,
base_value_destroyed: &impl ReadableVec<Height, Cents>,
up_to_1h_value_created: &impl ReadableVec<Height, Cents>,

View File

@@ -2,15 +2,15 @@ use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{
BasisPoints16, BasisPoints32, BasisPointsSigned16,
Bitcoin, Cents, CentsSats, CentsSigned, CentsSquaredSats, Dollars, Height, Sats, StoredF32, StoredF64, Version,
Bitcoin, Cents, CentsSats, CentsSigned, CentsSquaredSats, Dollars, Height, Indexes, Sats, StoredF32, StoredF64, Version,
};
use vecdb::{
AnyStoredVec, AnyVec, BytesVec, Exit, ImportableVec, ReadableCloneableVec,
AnyStoredVec, AnyVec, BytesVec, Exit, ReadableCloneableVec,
ReadableVec, Rw, StorageMode, WritableVec,
};
use crate::{
ComputeIndexes, blocks,
blocks,
distribution::state::RealizedState,
internal::{
CentsPlus, CentsUnsignedToDollars, ComputedFromHeightCumulative, ComputedFromHeight,
@@ -113,258 +113,87 @@ pub struct RealizedBase<M: StorageMode = Rw> {
impl RealizedBase {
/// Import realized base metrics from database.
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v0 = Version::ZERO;
let v1 = Version::ONE;
let v2 = Version::new(2);
let v3 = Version::new(3);
// Import combined types using forced_import which handles height + derived
let realized_cap_cents = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("realized_cap_cents"),
cfg.version,
cfg.indexes,
)?;
let realized_cap_cents = cfg.import_computed("realized_cap_cents", v0)?;
let realized_cap = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
&cfg.name("realized_cap"),
cfg.version,
realized_cap_cents.height.read_only_boxed_clone(),
&realized_cap_cents,
&cfg.name("realized_cap"), cfg.version,
realized_cap_cents.height.read_only_boxed_clone(), &realized_cap_cents,
);
let realized_profit = ComputedFromHeightCumulative::forced_import(
cfg.db,
&cfg.name("realized_profit"),
cfg.version,
cfg.indexes,
)?;
let realized_profit_ema_1w = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("realized_profit_ema_1w"),
cfg.version,
cfg.indexes,
)?;
let realized_loss = ComputedFromHeightCumulative::forced_import(
cfg.db,
&cfg.name("realized_loss"),
cfg.version,
cfg.indexes,
)?;
let realized_loss_ema_1w = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("realized_loss_ema_1w"),
cfg.version,
cfg.indexes,
)?;
let realized_profit = cfg.import_cumulative("realized_profit", v0)?;
let realized_profit_ema_1w = cfg.import_computed("realized_profit_ema_1w", v0)?;
let realized_loss = cfg.import_cumulative("realized_loss", v0)?;
let realized_loss_ema_1w = cfg.import_computed("realized_loss_ema_1w", v0)?;
let neg_realized_loss = LazyFromHeight::from_height_source::<NegCentsUnsignedToDollars>(
&cfg.name("neg_realized_loss"),
cfg.version + v1,
realized_loss.height.read_only_boxed_clone(),
cfg.indexes,
&cfg.name("neg_realized_loss"), cfg.version + Version::ONE,
realized_loss.height.read_only_boxed_clone(), cfg.indexes,
);
let net_realized_pnl = ComputedFromHeightCumulative::forced_import(
cfg.db,
&cfg.name("net_realized_pnl"),
cfg.version,
cfg.indexes,
)?;
let net_realized_pnl_ema_1w = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("net_realized_pnl_ema_1w"),
cfg.version,
cfg.indexes,
)?;
let peak_regret = ComputedFromHeightCumulative::forced_import(
cfg.db,
&cfg.name("realized_peak_regret"),
cfg.version + v2,
cfg.indexes,
)?;
let gross_pnl = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("gross_pnl"),
cfg.version,
cfg.indexes,
)?;
let net_realized_pnl = cfg.import_cumulative("net_realized_pnl", v0)?;
let net_realized_pnl_ema_1w = cfg.import_computed("net_realized_pnl_ema_1w", v0)?;
let peak_regret = cfg.import_cumulative("realized_peak_regret", Version::new(2))?;
let gross_pnl = cfg.import_fiat("realized_gross_pnl", v0)?;
let realized_profit_rel_to_realized_cap =
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("realized_profit_rel_to_realized_cap"),
cfg.version + v1,
cfg.indexes,
)?;
cfg.import_percent_bp16("realized_profit_rel_to_realized_cap", v1)?;
let realized_loss_rel_to_realized_cap =
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("realized_loss_rel_to_realized_cap"),
cfg.version + v1,
cfg.indexes,
)?;
cfg.import_percent_bp16("realized_loss_rel_to_realized_cap", v1)?;
let net_realized_pnl_rel_to_realized_cap =
PercentFromHeight::forced_import_bps16(
cfg.db,
&cfg.name("net_realized_pnl_rel_to_realized_cap"),
cfg.version + v1,
cfg.indexes,
)?;
cfg.import_percent_bps16("net_realized_pnl_rel_to_realized_cap", v1)?;
let realized_price = Price::forced_import(
cfg.db,
&cfg.name("realized_price"),
cfg.version + v1,
cfg.indexes,
)?;
let realized_price = cfg.import_price("realized_price", v1)?;
let investor_price = cfg.import_price("investor_price", v0)?;
let investor_price_ratio = cfg.import_ratio("investor_price", v0)?;
let lower_price_band = cfg.import_price("lower_price_band", v0)?;
let upper_price_band = cfg.import_price("upper_price_band", v0)?;
let investor_price = Price::forced_import(
cfg.db,
&cfg.name("investor_price"),
cfg.version,
cfg.indexes,
)?;
let cap_raw = cfg.import_bytes("cap_raw", v0)?;
let investor_cap_raw = cfg.import_bytes("investor_cap_raw", v0)?;
let investor_price_ratio = ComputedFromHeightRatio::forced_import(
cfg.db,
&cfg.name("investor_price"),
cfg.version,
cfg.indexes,
)?;
let lower_price_band = Price::forced_import(
cfg.db,
&cfg.name("lower_price_band"),
cfg.version,
cfg.indexes,
)?;
let upper_price_band = Price::forced_import(
cfg.db,
&cfg.name("upper_price_band"),
cfg.version,
cfg.indexes,
)?;
let cap_raw = BytesVec::forced_import(cfg.db, &cfg.name("cap_raw"), cfg.version)?;
let investor_cap_raw =
BytesVec::forced_import(cfg.db, &cfg.name("investor_cap_raw"), cfg.version)?;
let profit_value_created = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("profit_value_created"),
cfg.version,
cfg.indexes,
)?;
let profit_value_destroyed = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("profit_value_destroyed"),
cfg.version,
cfg.indexes,
)?;
let loss_value_created = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("loss_value_created"),
cfg.version,
cfg.indexes,
)?;
let loss_value_destroyed = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("loss_value_destroyed"),
cfg.version,
cfg.indexes,
)?;
let value_created = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("value_created"),
cfg.version,
cfg.indexes,
)?;
let value_destroyed = ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("value_destroyed"),
cfg.version,
cfg.indexes,
)?;
let profit_value_created = cfg.import_computed("profit_value_created", v0)?;
let profit_value_destroyed = cfg.import_computed("profit_value_destroyed", v0)?;
let loss_value_created = cfg.import_computed("loss_value_created", v0)?;
let loss_value_destroyed = cfg.import_computed("loss_value_destroyed", v0)?;
let value_created = cfg.import_computed("value_created", v0)?;
let value_destroyed = cfg.import_computed("value_destroyed", v0)?;
let capitulation_flow = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
&cfg.name("capitulation_flow"),
cfg.version,
loss_value_destroyed.height.read_only_boxed_clone(),
&loss_value_destroyed,
&cfg.name("capitulation_flow"), cfg.version,
loss_value_destroyed.height.read_only_boxed_clone(), &loss_value_destroyed,
);
let profit_flow = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
&cfg.name("profit_flow"),
cfg.version,
profit_value_destroyed.height.read_only_boxed_clone(),
&profit_value_destroyed,
&cfg.name("profit_flow"), cfg.version,
profit_value_destroyed.height.read_only_boxed_clone(), &profit_value_destroyed,
);
let realized_price_ratio = ComputedFromHeightRatio::forced_import(
cfg.db,
&cfg.name("realized_price"),
cfg.version + v1,
cfg.indexes,
)?;
let realized_price_ratio = cfg.import_ratio("realized_price", v1)?;
let mvrv = LazyFromHeight::from_lazy::<Identity<StoredF32>, BasisPoints32>(
&cfg.name("mvrv"),
cfg.version,
&realized_price_ratio.ratio,
&cfg.name("mvrv"), cfg.version, &realized_price_ratio.ratio,
);
// === Rolling windows ===
let value_created_sum = RollingWindows::forced_import(
cfg.db, &cfg.name("value_created"), cfg.version + v1, cfg.indexes,
)?;
let value_destroyed_sum = RollingWindows::forced_import(
cfg.db, &cfg.name("value_destroyed"), cfg.version + v1, cfg.indexes,
)?;
let gross_pnl_sum = RollingWindows::forced_import(
cfg.db, &cfg.name("gross_pnl_sum"), cfg.version + v1, cfg.indexes,
)?;
let sopr = RollingWindows::forced_import(
cfg.db, &cfg.name("sopr"), cfg.version + v1, cfg.indexes,
)?;
let sell_side_risk_ratio = PercentRollingWindows::forced_import_bp16(
cfg.db, &cfg.name("sell_side_risk_ratio"), cfg.version + v1, cfg.indexes,
)?;
// Rolling windows
let value_created_sum = cfg.import_rolling("value_created", v1)?;
let value_destroyed_sum = cfg.import_rolling("value_destroyed", v1)?;
let gross_pnl_sum = cfg.import_rolling("gross_pnl_sum", v1)?;
let sopr = cfg.import_rolling("sopr", v1)?;
let sell_side_risk_ratio = cfg.import_percent_rolling_bp16("sell_side_risk_ratio", v1)?;
// === EMA imports ===
let sopr_24h_ema = RollingEmas1w1m::forced_import(
cfg.db, &cfg.name("sopr_24h"), cfg.version + v1, cfg.indexes,
)?;
let sell_side_risk_ratio_24h_ema = PercentRollingEmas1w1m::forced_import_bp16(
cfg.db, &cfg.name("sell_side_risk_ratio_24h"), cfg.version + v1, cfg.indexes,
)?;
// EMAs
let sopr_24h_ema = cfg.import_emas_1w_1m("sopr_24h", v1)?;
let sell_side_risk_ratio_24h_ema = cfg.import_percent_emas_1w_1m_bp16("sell_side_risk_ratio_24h", v1)?;
let peak_regret_rel_to_realized_cap =
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("realized_peak_regret_rel_to_realized_cap"),
cfg.version + v1,
cfg.indexes,
)?;
cfg.import_percent_bp16("realized_peak_regret_rel_to_realized_cap", v1)?;
Ok(Self {
realized_cap_cents,
realized_cap,
realized_price,
realized_price_ratio,
realized_cap_change_1m: ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("realized_cap_change_1m"),
cfg.version,
cfg.indexes,
)?,
realized_cap_change_1m: cfg.import_computed("realized_cap_change_1m", v0)?,
investor_price,
investor_price_ratio,
lower_price_band,
@@ -398,52 +227,17 @@ impl RealizedBase {
gross_pnl_sum,
sell_side_risk_ratio,
sell_side_risk_ratio_24h_ema,
net_pnl_change_1m: ComputedFromHeight::forced_import(
cfg.db,
&cfg.name("net_pnl_change_1m"),
cfg.version + v3,
cfg.indexes,
)?,
net_pnl_change_1m: cfg.import_computed("net_pnl_change_1m", Version::new(3))?,
net_pnl_change_1m_rel_to_realized_cap:
PercentFromHeight::forced_import_bps16(
cfg.db,
&cfg.name("net_pnl_change_1m_rel_to_realized_cap"),
cfg.version + v3,
cfg.indexes,
)?,
cfg.import_percent_bps16("net_pnl_change_1m_rel_to_realized_cap", Version::new(3))?,
net_pnl_change_1m_rel_to_market_cap:
PercentFromHeight::forced_import_bps16(
cfg.db,
&cfg.name("net_pnl_change_1m_rel_to_market_cap"),
cfg.version + v3,
cfg.indexes,
)?,
cfg.import_percent_bps16("net_pnl_change_1m_rel_to_market_cap", Version::new(3))?,
peak_regret,
peak_regret_rel_to_realized_cap,
sent_in_profit: ValueFromHeightCumulative::forced_import(
cfg.db,
&cfg.name("sent_in_profit"),
cfg.version,
cfg.indexes,
)?,
sent_in_profit_ema: RollingEmas2w::forced_import(
cfg.db,
&cfg.name("sent_in_profit"),
cfg.version,
cfg.indexes,
)?,
sent_in_loss: ValueFromHeightCumulative::forced_import(
cfg.db,
&cfg.name("sent_in_loss"),
cfg.version,
cfg.indexes,
)?,
sent_in_loss_ema: RollingEmas2w::forced_import(
cfg.db,
&cfg.name("sent_in_loss"),
cfg.version,
cfg.indexes,
)?,
sent_in_profit: cfg.import_value_cumulative("sent_in_profit", v0)?,
sent_in_profit_ema: cfg.import_emas_2w("sent_in_profit", v0)?,
sent_in_loss: cfg.import_value_cumulative("sent_in_loss", v0)?,
sent_in_loss_ema: cfg.import_emas_2w("sent_in_loss", v0)?,
})
}
@@ -534,7 +328,7 @@ impl RealizedBase {
/// Compute aggregate values from separate cohorts.
pub(crate) fn compute_from_stateful(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {
@@ -683,7 +477,7 @@ impl RealizedBase {
/// First phase of computed metrics (indexes from height).
pub(crate) fn compute_rest_part1(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.realized_profit
@@ -724,7 +518,7 @@ impl RealizedBase {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
exit: &Exit,

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{BasisPoints16, Cents, Dollars, Height, StoredF64, Version};
use brk_types::{BasisPoints16, Cents, Dollars, Height, Indexes, StoredF64, Version};
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::{
ComputeIndexes, blocks,
blocks,
internal::{
ComputedFromHeightRatioExtension, PercentFromHeight,
RatioCents64, RatioDollarsBp16, RollingWindows,
@@ -34,35 +34,16 @@ pub struct RealizedExtended<M: StorageMode = Rw> {
impl RealizedExtended {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v1 = Version::ONE;
Ok(RealizedExtended {
realized_cap_rel_to_own_market_cap: PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("realized_cap_rel_to_own_market_cap"),
cfg.version,
cfg.indexes,
)?,
realized_profit_sum: RollingWindows::forced_import(
cfg.db, &cfg.name("realized_profit"), cfg.version + v1, cfg.indexes,
)?,
realized_loss_sum: RollingWindows::forced_import(
cfg.db, &cfg.name("realized_loss"), cfg.version + v1, cfg.indexes,
)?,
realized_profit_to_loss_ratio: RollingWindows::forced_import(
cfg.db, &cfg.name("realized_profit_to_loss_ratio"), cfg.version + v1, cfg.indexes,
)?,
realized_cap_rel_to_own_market_cap: cfg.import_percent_bp16("realized_cap_rel_to_own_market_cap", Version::ZERO)?,
realized_profit_sum: cfg.import_rolling("realized_profit", Version::ONE)?,
realized_loss_sum: cfg.import_rolling("realized_loss", Version::ONE)?,
realized_profit_to_loss_ratio: cfg.import_rolling("realized_profit_to_loss_ratio", Version::ONE)?,
realized_price_ratio_ext: ComputedFromHeightRatioExtension::forced_import(
cfg.db,
&cfg.name("realized_price"),
cfg.version + v1,
cfg.indexes,
cfg.db, &cfg.name("realized_price"), cfg.version + Version::ONE, cfg.indexes,
)?,
investor_price_ratio_ext: ComputedFromHeightRatioExtension::forced_import(
cfg.db,
&cfg.name("investor_price"),
cfg.version,
cfg.indexes,
cfg.db, &cfg.name("investor_price"), cfg.version, cfg.indexes,
)?,
})
}
@@ -72,7 +53,7 @@ impl RealizedExtended {
&mut self,
base: &RealizedBase,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
exit: &Exit,
) -> Result<()> {

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Cents, Dollars, Height};
use brk_types::{Bitcoin, Cents, Dollars, Height, Indexes};
use derive_more::{Deref, DerefMut};
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, prices};
use crate::{blocks, prices};
use crate::distribution::metrics::ImportConfig;
@@ -33,7 +33,7 @@ impl RealizedWithAdjusted {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
up_to_1h_value_created: &impl ReadableVec<Height, Cents>,

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Dollars, Height};
use brk_types::{Bitcoin, Dollars, Height, Indexes};
use derive_more::{Deref, DerefMut};
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, prices};
use crate::{blocks, prices};
use crate::distribution::metrics::ImportConfig;
@@ -33,7 +33,7 @@ impl RealizedWithExtended {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
exit: &Exit,

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Cents, Dollars, Height};
use brk_types::{Bitcoin, Cents, Dollars, Height, Indexes};
use derive_more::{Deref, DerefMut};
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, prices};
use crate::{blocks, prices};
use crate::distribution::metrics::ImportConfig;
@@ -40,7 +40,7 @@ impl RealizedWithExtendedAdjusted {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
up_to_1h_value_created: &impl ReadableVec<Height, Cents>,

View File

@@ -37,9 +37,7 @@ impl RelativeBase {
let v2 = Version::new(2);
let net_unrealized_pnl_rel_to_market_cap =
PercentFromHeight::forced_import_bps16(
cfg.db, &cfg.name("net_unrealized_pnl_rel_to_market_cap"), cfg.version + v2, cfg.indexes,
)?;
cfg.import_percent_bps16("net_unrealized_pnl_rel_to_market_cap", v2)?;
let nupl = LazyFromHeight::from_computed::<Bps16ToFloat>(
&cfg.name("nupl"),
@@ -50,35 +48,21 @@ impl RelativeBase {
Ok(Self {
supply_in_profit_rel_to_own_supply:
PercentFromHeight::forced_import_bp16(
cfg.db, &cfg.name("supply_in_profit_rel_to_own_supply"), cfg.version + v1, cfg.indexes,
)?,
cfg.import_percent_bp16("supply_in_profit_rel_to_own_supply", v1)?,
supply_in_loss_rel_to_own_supply:
PercentFromHeight::forced_import_bp16(
cfg.db, &cfg.name("supply_in_loss_rel_to_own_supply"), cfg.version + v1, cfg.indexes,
)?,
cfg.import_percent_bp16("supply_in_loss_rel_to_own_supply", v1)?,
unrealized_profit_rel_to_market_cap:
PercentFromHeight::forced_import_bp16(
cfg.db, &cfg.name("unrealized_profit_rel_to_market_cap"), cfg.version + v2, cfg.indexes,
)?,
cfg.import_percent_bp16("unrealized_profit_rel_to_market_cap", v2)?,
unrealized_loss_rel_to_market_cap:
PercentFromHeight::forced_import_bp16(
cfg.db, &cfg.name("unrealized_loss_rel_to_market_cap"), cfg.version + v2, cfg.indexes,
)?,
cfg.import_percent_bp16("unrealized_loss_rel_to_market_cap", v2)?,
neg_unrealized_loss_rel_to_market_cap:
PercentFromHeight::forced_import_bps16(
cfg.db, &cfg.name("neg_unrealized_loss_rel_to_market_cap"), cfg.version + v2, cfg.indexes,
)?,
cfg.import_percent_bps16("neg_unrealized_loss_rel_to_market_cap", v2)?,
net_unrealized_pnl_rel_to_market_cap,
nupl,
invested_capital_in_profit_rel_to_realized_cap:
PercentFromHeight::forced_import_bp16(
cfg.db, &cfg.name("invested_capital_in_profit_rel_to_realized_cap"), cfg.version, cfg.indexes,
)?,
cfg.import_percent_bp16("invested_capital_in_profit_rel_to_realized_cap", Version::ZERO)?,
invested_capital_in_loss_rel_to_realized_cap:
PercentFromHeight::forced_import_bp16(
cfg.db, &cfg.name("invested_capital_in_loss_rel_to_realized_cap"), cfg.version, cfg.indexes,
)?,
cfg.import_percent_bp16("invested_capital_in_loss_rel_to_realized_cap", Version::ZERO)?,
})
}

View File

@@ -1,6 +1,6 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{BasisPoints16, BasisPointsSigned16, Dollars, Height};
use brk_types::{BasisPoints16, BasisPointsSigned16, Dollars, Height, Version};
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::internal::{
@@ -23,40 +23,18 @@ pub struct RelativeExtendedOwnMarketCap<M: StorageMode = Rw> {
}
impl RelativeExtendedOwnMarketCap {
pub(crate) fn forced_import(
cfg: &ImportConfig,
) -> Result<Self> {
let v2 = brk_types::Version::new(2);
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v2 = Version::new(2);
Ok(Self {
unrealized_profit_rel_to_own_market_cap:
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("unrealized_profit_rel_to_own_market_cap"),
cfg.version + v2,
cfg.indexes,
)?,
cfg.import_percent_bp16("unrealized_profit_rel_to_own_market_cap", v2)?,
unrealized_loss_rel_to_own_market_cap:
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("unrealized_loss_rel_to_own_market_cap"),
cfg.version + v2,
cfg.indexes,
)?,
cfg.import_percent_bp16("unrealized_loss_rel_to_own_market_cap", v2)?,
neg_unrealized_loss_rel_to_own_market_cap:
PercentFromHeight::forced_import_bps16(
cfg.db,
&cfg.name("neg_unrealized_loss_rel_to_own_market_cap"),
cfg.version + v2,
cfg.indexes,
)?,
cfg.import_percent_bps16("neg_unrealized_loss_rel_to_own_market_cap", v2)?,
net_unrealized_pnl_rel_to_own_market_cap:
PercentFromHeight::forced_import_bps16(
cfg.db,
&cfg.name("net_unrealized_pnl_rel_to_own_market_cap"),
cfg.version + v2,
cfg.indexes,
)?,
cfg.import_percent_bps16("net_unrealized_pnl_rel_to_own_market_cap", v2)?,
})
}

View File

@@ -1,6 +1,6 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{BasisPoints16, BasisPointsSigned16, Dollars, Height};
use brk_types::{BasisPoints16, BasisPointsSigned16, Dollars, Height, Version};
use vecdb::{Exit, Rw, StorageMode};
use crate::internal::{
@@ -23,41 +23,19 @@ pub struct RelativeExtendedOwnPnl<M: StorageMode = Rw> {
}
impl RelativeExtendedOwnPnl {
pub(crate) fn forced_import(
cfg: &ImportConfig,
) -> Result<Self> {
let v1 = brk_types::Version::ONE;
let v2 = brk_types::Version::new(2);
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v1 = Version::ONE;
let v2 = Version::new(2);
Ok(Self {
unrealized_profit_rel_to_own_gross_pnl:
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("unrealized_profit_rel_to_own_gross_pnl"),
cfg.version + v1,
cfg.indexes,
)?,
cfg.import_percent_bp16("unrealized_profit_rel_to_own_gross_pnl", v1)?,
unrealized_loss_rel_to_own_gross_pnl:
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("unrealized_loss_rel_to_own_gross_pnl"),
cfg.version + v1,
cfg.indexes,
)?,
cfg.import_percent_bp16("unrealized_loss_rel_to_own_gross_pnl", v1)?,
neg_unrealized_loss_rel_to_own_gross_pnl:
PercentFromHeight::forced_import_bps16(
cfg.db,
&cfg.name("neg_unrealized_loss_rel_to_own_gross_pnl"),
cfg.version + v1,
cfg.indexes,
)?,
cfg.import_percent_bps16("neg_unrealized_loss_rel_to_own_gross_pnl", v1)?,
net_unrealized_pnl_rel_to_own_gross_pnl:
PercentFromHeight::forced_import_bps16(
cfg.db,
&cfg.name("net_unrealized_pnl_rel_to_own_gross_pnl"),
cfg.version + v2,
cfg.indexes,
)?,
cfg.import_percent_bps16("net_unrealized_pnl_rel_to_own_gross_pnl", v2)?,
})
}

View File

@@ -1,6 +1,6 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{BasisPoints16, Height, Sats};
use brk_types::{BasisPoints16, Height, Sats, Version};
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::internal::{PercentFromHeight, RatioSatsBp16};
@@ -19,31 +19,14 @@ pub struct RelativeToAll<M: StorageMode = Rw> {
}
impl RelativeToAll {
pub(crate) fn forced_import(
cfg: &ImportConfig,
) -> Result<Self> {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
Ok(Self {
supply_rel_to_circulating_supply:
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("supply_rel_to_circulating_supply"),
cfg.version + brk_types::Version::ONE,
cfg.indexes,
)?,
cfg.import_percent_bp16("supply_rel_to_circulating_supply", Version::ONE)?,
supply_in_profit_rel_to_circulating_supply:
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("supply_in_profit_rel_to_circulating_supply"),
cfg.version + brk_types::Version::ONE,
cfg.indexes,
)?,
cfg.import_percent_bp16("supply_in_profit_rel_to_circulating_supply", Version::ONE)?,
supply_in_loss_rel_to_circulating_supply:
PercentFromHeight::forced_import_bp16(
cfg.db,
&cfg.name("supply_in_loss_rel_to_circulating_supply"),
cfg.version + brk_types::Version::ONE,
cfg.indexes,
)?,
cfg.import_percent_bp16("supply_in_loss_rel_to_circulating_supply", Version::ONE)?,
})
}

View File

@@ -1,8 +1,8 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, Sats, Version};
use brk_types::{Height, Indexes, Sats, Version};
use crate::{ComputeIndexes, blocks, prices};
use crate::{blocks, prices};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
@@ -25,12 +25,7 @@ pub struct SupplyMetrics<M: StorageMode = Rw> {
impl SupplyMetrics {
/// Import supply metrics from database.
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let supply = ValueFromHeight::forced_import(
cfg.db,
&cfg.name("supply"),
cfg.version,
cfg.indexes,
)?;
let supply = cfg.import_value("supply", Version::ZERO)?;
let supply_halved = LazyValueFromHeight::from_block_source::<
HalveSats,
@@ -39,12 +34,7 @@ impl SupplyMetrics {
HalveDollars,
>(&cfg.name("supply_halved"), &supply, cfg.version);
let change_1m = ValueFromHeightChange::forced_import(
cfg.db,
&cfg.name("supply_change_1m"),
cfg.version,
cfg.indexes,
)?;
let change_1m = cfg.import_value_change("supply_change_1m", Version::ZERO)?;
Ok(Self {
total: supply,
@@ -92,7 +82,7 @@ impl SupplyMetrics {
/// Compute aggregate values from separate cohorts.
pub(crate) fn compute_from_stateful(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {
@@ -111,7 +101,7 @@ impl SupplyMetrics {
pub(crate) fn compute_rest_part1(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.change_1m.compute_rolling(

View File

@@ -1,13 +1,12 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, CentsSats, CentsSigned, CentsSquaredSats, Height, Version};
use brk_types::{Cents, CentsSats, CentsSigned, CentsSquaredSats, Height, Indexes, Version};
use vecdb::{
AnyStoredVec, AnyVec, BytesVec, Exit, ImportableVec, ReadableCloneableVec, ReadableVec,
AnyStoredVec, AnyVec, BytesVec, Exit, ReadableCloneableVec, ReadableVec,
Rw, StorageMode, WritableVec,
};
use crate::{
ComputeIndexes,
distribution::state::UnrealizedState,
internal::{
CentsSubtractToCentsSigned, FiatFromHeight, LazyFromHeight, NegCentsUnsignedToDollars,
@@ -56,84 +55,24 @@ pub struct UnrealizedBase<M: StorageMode = Rw> {
impl UnrealizedBase {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let supply_in_profit = ValueFromHeight::forced_import(
cfg.db,
&cfg.name("supply_in_profit"),
cfg.version,
cfg.indexes,
)?;
let supply_in_loss = ValueFromHeight::forced_import(
cfg.db,
&cfg.name("supply_in_loss"),
cfg.version,
cfg.indexes,
)?;
let v0 = Version::ZERO;
let supply_in_profit = cfg.import_value("supply_in_profit", v0)?;
let supply_in_loss = cfg.import_value("supply_in_loss", v0)?;
let unrealized_profit = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("unrealized_profit"),
cfg.version,
cfg.indexes,
)?;
let unrealized_loss = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("unrealized_loss"),
cfg.version,
cfg.indexes,
)?;
let unrealized_profit = cfg.import_fiat("unrealized_profit", v0)?;
let unrealized_loss = cfg.import_fiat("unrealized_loss", v0)?;
let invested_capital_in_profit = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("invested_capital_in_profit"),
cfg.version,
cfg.indexes,
)?;
let invested_capital_in_loss = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("invested_capital_in_loss"),
cfg.version,
cfg.indexes,
)?;
let invested_capital_in_profit = cfg.import_fiat("invested_capital_in_profit", v0)?;
let invested_capital_in_loss = cfg.import_fiat("invested_capital_in_loss", v0)?;
let invested_capital_in_profit_raw = BytesVec::forced_import(
cfg.db,
&cfg.name("invested_capital_in_profit_raw"),
cfg.version,
)?;
let invested_capital_in_loss_raw = BytesVec::forced_import(
cfg.db,
&cfg.name("invested_capital_in_loss_raw"),
cfg.version,
)?;
let investor_cap_in_profit_raw = BytesVec::forced_import(
cfg.db,
&cfg.name("investor_cap_in_profit_raw"),
cfg.version,
)?;
let investor_cap_in_loss_raw = BytesVec::forced_import(
cfg.db,
&cfg.name("investor_cap_in_loss_raw"),
cfg.version,
)?;
let invested_capital_in_profit_raw = cfg.import_bytes("invested_capital_in_profit_raw", v0)?;
let invested_capital_in_loss_raw = cfg.import_bytes("invested_capital_in_loss_raw", v0)?;
let investor_cap_in_profit_raw = cfg.import_bytes("investor_cap_in_profit_raw", v0)?;
let investor_cap_in_loss_raw = cfg.import_bytes("investor_cap_in_loss_raw", v0)?;
let pain_index = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("pain_index"),
cfg.version,
cfg.indexes,
)?;
let greed_index = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("greed_index"),
cfg.version,
cfg.indexes,
)?;
let net_sentiment = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("net_sentiment"),
cfg.version + Version::ONE,
cfg.indexes,
)?;
let pain_index = cfg.import_fiat("pain_index", v0)?;
let greed_index = cfg.import_fiat("greed_index", v0)?;
let net_sentiment = cfg.import_fiat("net_sentiment", Version::ONE)?;
let neg_unrealized_loss = LazyFromHeight::from_computed::<NegCentsUnsignedToDollars>(
&cfg.name("neg_unrealized_loss"),
@@ -142,18 +81,8 @@ impl UnrealizedBase {
&unrealized_loss.cents,
);
let net_unrealized_pnl = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("net_unrealized_pnl"),
cfg.version,
cfg.indexes,
)?;
let gross_pnl = FiatFromHeight::forced_import(
cfg.db,
&cfg.name("gross_pnl"),
cfg.version,
cfg.indexes,
)?;
let net_unrealized_pnl = cfg.import_fiat("net_unrealized_pnl", v0)?;
let gross_pnl = cfg.import_fiat("unrealized_gross_pnl", v0)?;
Ok(Self {
supply_in_profit,
@@ -260,7 +189,7 @@ impl UnrealizedBase {
pub(crate) fn compute_from_stateful(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {
@@ -392,7 +321,7 @@ impl UnrealizedBase {
pub(crate) fn compute_rest(
&mut self,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// Pain index: investor_price_of_losers - spot
@@ -457,7 +386,7 @@ impl UnrealizedBase {
/// Compute net_sentiment.height for separate cohorts (greed - pain).
pub(crate) fn compute_net_sentiment_height(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.net_sentiment

View File

@@ -4,8 +4,8 @@ use brk_error::Result;
use brk_indexer::Indexer;
use brk_traversable::Traversable;
use brk_types::{
Cents, Day1, EmptyAddressData, EmptyAddressIndex, FundedAddressData, FundedAddressIndex,
Height, SupplyState, Timestamp, TxIndex, Version,
Cents, EmptyAddressData, EmptyAddressIndex, FundedAddressData, FundedAddressIndex,
Height, Indexes, SupplyState, Timestamp, TxIndex, Version,
};
use tracing::{debug, info};
use vecdb::{
@@ -14,7 +14,7 @@ use vecdb::{
};
use crate::{
ComputeIndexes, blocks,
blocks,
distribution::{
compute::{
PriceRangeMax, StartMode, determine_start_mode, process_blocks, recover_state,
@@ -208,7 +208,7 @@ impl Vecs {
transactions: &transactions::Vecs,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &mut ComputeIndexes,
starting_indexes: &mut Indexes,
exit: &Exit,
) -> Result<()> {
let cache_target_len = prices
@@ -336,16 +336,6 @@ impl Vecs {
// 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 day1 to match
if starting_height.is_zero() {
starting_indexes.day1 = Day1::from(0);
} else {
starting_indexes.day1 = indexes
.height
.day1
.collect_one(starting_height.decremented().unwrap())
.unwrap();
}
}
// 2b. Validate computed versions

View File

@@ -33,7 +33,6 @@ use vecdb::{Database, Exit, PAGE_SIZE, ReadableVec, Rw, StorageMode};
use crate::blocks;
pub use address::Vecs as AddressVecs;
pub use brk_types::ComputeIndexes;
pub use day1::Vecs as Day1Vecs;
pub use day3::Vecs as Day3Vecs;
pub use difficultyepoch::Vecs as DifficultyEpochVecs;
@@ -133,7 +132,7 @@ impl Vecs {
blocks: &mut blocks::Vecs,
starting_indexes: Indexes,
exit: &Exit,
) -> Result<ComputeIndexes> {
) -> Result<Indexes> {
blocks
.time
.compute(indexer, starting_indexes.height, exit)?;
@@ -149,7 +148,7 @@ impl Vecs {
blocks_time: &blocks::time::Vecs,
starting_indexes: Indexes,
exit: &Exit,
) -> Result<ComputeIndexes> {
) -> Result<Indexes> {
// Transaction indexes - compute input/output counts
self.txindex.input_count.compute_count_from_indexes(
starting_indexes.txindex,
@@ -350,71 +349,10 @@ impl Vecs {
exit,
)?;
// --- Starting values from height → period mappings ---
let starting_minute10 = self
.height
.minute10
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_minute30 = self
.height
.minute30
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_hour1 = self
.height
.hour1
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_hour4 = self
.height
.hour4
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_hour12 = self
.height
.hour12
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_day3 = self
.height
.day3
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_week1 = self
.height
.week1
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_month1 = self
.height
.month1
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_month3 = self
.height
.month3
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_month6 = self
.height
.month6
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_year1 = self
.height
.year1
.collect_one(decremented_starting_height)
.unwrap_or_default();
let starting_year10 = self
.height
.year10
.collect_one(decremented_starting_height)
.unwrap_or_default();
// --- Compute period-level vecs (first_height + identity) ---
let prev_height = decremented_starting_height;
// Minute10
self.minute10.first_height.compute_first_per_index(
starting_indexes.height,
@@ -422,7 +360,7 @@ impl Vecs {
exit,
)?;
self.minute10.identity.compute_from_index(
starting_minute10,
self.height.minute10.collect_one(prev_height).unwrap_or_default(),
&self.minute10.first_height,
exit,
)?;
@@ -434,7 +372,7 @@ impl Vecs {
exit,
)?;
self.minute30.identity.compute_from_index(
starting_minute30,
self.height.minute30.collect_one(prev_height).unwrap_or_default(),
&self.minute30.first_height,
exit,
)?;
@@ -445,9 +383,11 @@ impl Vecs {
&self.height.hour1,
exit,
)?;
self.hour1
.identity
.compute_from_index(starting_hour1, &self.hour1.first_height, exit)?;
self.hour1.identity.compute_from_index(
self.height.hour1.collect_one(prev_height).unwrap_or_default(),
&self.hour1.first_height,
exit,
)?;
// Hour4
self.hour4.first_height.compute_first_per_index(
@@ -455,9 +395,11 @@ impl Vecs {
&self.height.hour4,
exit,
)?;
self.hour4
.identity
.compute_from_index(starting_hour4, &self.hour4.first_height, exit)?;
self.hour4.identity.compute_from_index(
self.height.hour4.collect_one(prev_height).unwrap_or_default(),
&self.hour4.first_height,
exit,
)?;
// Hour12
self.hour12.first_height.compute_first_per_index(
@@ -466,7 +408,7 @@ impl Vecs {
exit,
)?;
self.hour12.identity.compute_from_index(
starting_hour12,
self.height.hour12.collect_one(prev_height).unwrap_or_default(),
&self.hour12.first_height,
exit,
)?;
@@ -477,9 +419,11 @@ impl Vecs {
&self.height.day1,
exit,
)?;
self.day1
.identity
.compute_from_index(starting_day1, &self.day1.first_height, exit)?;
self.day1.identity.compute_from_index(
starting_day1,
&self.day1.first_height,
exit,
)?;
self.day1.date.compute_transform(
starting_day1,
&self.day1.identity,
@@ -499,9 +443,11 @@ impl Vecs {
&self.height.day3,
exit,
)?;
self.day3
.identity
.compute_from_index(starting_day3, &self.day3.first_height, exit)?;
self.day3.identity.compute_from_index(
self.height.day3.collect_one(prev_height).unwrap_or_default(),
&self.day3.first_height,
exit,
)?;
let blocks_time_date = &blocks_time.date;
@@ -511,9 +457,12 @@ impl Vecs {
&self.height.week1,
exit,
)?;
self.week1
.identity
.compute_from_index(starting_week1, &self.week1.first_height, exit)?;
let starting_week1 = self.height.week1.collect_one(prev_height).unwrap_or_default();
self.week1.identity.compute_from_index(
starting_week1,
&self.week1.first_height,
exit,
)?;
self.week1.date.compute_transform(
starting_week1,
&self.week1.first_height,
@@ -527,6 +476,7 @@ impl Vecs {
&self.height.month1,
exit,
)?;
let starting_month1 = self.height.month1.collect_one(prev_height).unwrap_or_default();
self.month1.identity.compute_from_index(
starting_month1,
&self.month1.first_height,
@@ -545,6 +495,7 @@ impl Vecs {
&self.height.month3,
exit,
)?;
let starting_month3 = self.height.month3.collect_one(prev_height).unwrap_or_default();
self.month3.identity.compute_from_index(
starting_month3,
&self.month3.first_height,
@@ -563,6 +514,7 @@ impl Vecs {
&self.height.month6,
exit,
)?;
let starting_month6 = self.height.month6.collect_one(prev_height).unwrap_or_default();
self.month6.identity.compute_from_index(
starting_month6,
&self.month6.first_height,
@@ -581,9 +533,12 @@ impl Vecs {
&self.height.year1,
exit,
)?;
self.year1
.identity
.compute_from_index(starting_year1, &self.year1.first_height, exit)?;
let starting_year1 = self.height.year1.collect_one(prev_height).unwrap_or_default();
self.year1.identity.compute_from_index(
starting_year1,
&self.year1.first_height,
exit,
)?;
self.year1.date.compute_transform(
starting_year1,
&self.year1.first_height,
@@ -597,6 +552,7 @@ impl Vecs {
&self.height.year10,
exit,
)?;
let starting_year10 = self.height.year10.collect_one(prev_height).unwrap_or_default();
self.year10.identity.compute_from_index(
starting_year10,
&self.year10.first_height,
@@ -609,23 +565,6 @@ impl Vecs {
exit,
)?;
Ok(ComputeIndexes::new(
starting_indexes,
starting_minute10,
starting_minute30,
starting_hour1,
starting_hour4,
starting_hour12,
starting_day1,
starting_day3,
starting_week1,
starting_month1,
starting_month3,
starting_month6,
starting_year1,
starting_year10,
starting_halvingepoch,
starting_difficultyepoch,
))
Ok(starting_indexes)
}
}

View File

@@ -1,9 +1,10 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::Indexes;
use vecdb::Exit;
use super::Vecs;
use crate::{blocks, indexes, ComputeIndexes};
use crate::{blocks, indexes};
impl Vecs {
pub(crate) fn compute(
@@ -11,7 +12,7 @@ impl Vecs {
indexer: &Indexer,
indexes: &indexes::Vecs,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.spent

View File

@@ -1,9 +1,10 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::Indexes;
use vecdb::Exit;
use super::Vecs;
use crate::{blocks, indexes, ComputeIndexes};
use crate::{blocks, indexes};
impl Vecs {
pub(crate) fn compute(
@@ -11,7 +12,7 @@ impl Vecs {
indexer: &Indexer,
indexes: &indexes::Vecs,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = blocks.count.window_starts();

View File

@@ -1,11 +1,10 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Sats, TxInIndex, TxIndex, TxOutIndex, Vout};
use brk_types::{Indexes, Sats, TxInIndex, TxIndex, TxOutIndex, Vout};
use tracing::info;
use vecdb::{AnyStoredVec, AnyVec, Database, Exit, WritableVec, ReadableVec, VecIndex};
use super::Vecs;
use crate::ComputeIndexes;
const BATCH_SIZE: usize = 2 * 1024 * 1024 * 1024 / size_of::<Entry>();
@@ -14,7 +13,7 @@ impl Vecs {
&mut self,
db: &Database,
indexer: &Indexer,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// Validate computed versions against dependencies

View File

@@ -17,6 +17,23 @@ pub struct DistributionStats<A, B = A, C = A, D = A, E = A, F = A, G = A, H = A>
}
impl<A> DistributionStats<A> {
pub const SUFFIXES: [&'static str; 8] = ["average", "min", "max", "p10", "p25", "median", "p75", "p90"];
pub fn try_from_fn<E>(
mut f: impl FnMut(&str) -> std::result::Result<A, E>,
) -> std::result::Result<Self, E> {
Ok(Self {
average: f(Self::SUFFIXES[0])?,
min: f(Self::SUFFIXES[1])?,
max: f(Self::SUFFIXES[2])?,
pct10: f(Self::SUFFIXES[3])?,
pct25: f(Self::SUFFIXES[4])?,
median: f(Self::SUFFIXES[5])?,
pct75: f(Self::SUFFIXES[6])?,
pct90: f(Self::SUFFIXES[7])?,
})
}
/// Apply a fallible operation to each of the 8 fields.
pub fn try_for_each_mut(&mut self, mut f: impl FnMut(&mut A) -> brk_error::Result<()>) -> brk_error::Result<()> {
f(&mut self.average)?;

View File

@@ -1,4 +1,4 @@
//! EagerIndexes - newtype on Indexes with EagerVec<PcoVec<I, T>> per field.
//! EagerIndexes - newtype on PerPeriod with EagerVec<PcoVec<I, T>> per field.
//!
//! Used for data eagerly computed and stored per period during indexing,
//! such as timestamp (first value per period) and OHLC (first/min/max per period).
@@ -8,7 +8,7 @@ use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour4, Hour12,
Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
Indexes, Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
};
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
@@ -18,15 +18,15 @@ use vecdb::{
};
use crate::{
ComputeIndexes, indexes, indexes_apply, indexes_from,
internal::{ComputedVecValue, Indexes, NumericValue},
indexes, indexes_apply, indexes_from,
internal::{ComputedVecValue, NumericValue, PerPeriod},
};
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct EagerIndexes<T, M: StorageMode = Rw>(
#[allow(clippy::type_complexity)]
pub Indexes<
pub PerPeriod<
<M as StorageMode>::Stored<EagerVec<PcoVec<Minute10, T>>>,
<M as StorageMode>::Stored<EagerVec<PcoVec<Minute30, T>>>,
<M as StorageMode>::Stored<EagerVec<PcoVec<Hour1, T>>>,
@@ -68,15 +68,17 @@ where
/// Compute "first value per period" — for each period, looks up `source[first_height[period]]`.
pub(crate) fn compute_first(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_source: &impl ReadableVec<Height, T>,
indexes: &indexes::Vecs,
exit: &Exit,
) -> Result<()> {
let prev_height = starting_indexes.height.decremented().unwrap_or_default();
macro_rules! period {
($field:ident) => {
self.0.$field.compute_indirect_sequential(
starting_indexes.$field,
indexes.height.$field.collect_one(prev_height).unwrap_or_default(),
&indexes.$field.first_height,
height_source,
exit,
@@ -92,18 +94,19 @@ where
/// Compute "max value per period" — for each period, finds `max(source[first_height[period]..first_height[period+1]])`.
pub(crate) fn compute_max(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_source: &impl ReadableVec<Height, T>,
indexes: &indexes::Vecs,
exit: &Exit,
) -> Result<()> {
let src_len = height_source.len();
let prev_height = starting_indexes.height.decremented().unwrap_or_default();
macro_rules! period {
($field:ident) => {
compute_period_extremum(
&mut self.0.$field,
starting_indexes.$field,
indexes.height.$field.collect_one(prev_height).unwrap_or_default(),
&indexes.$field.first_height,
height_source,
src_len,
@@ -121,18 +124,19 @@ where
/// Compute "min value per period" — for each period, finds `min(source[first_height[period]..first_height[period+1]])`.
pub(crate) fn compute_min(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_source: &impl ReadableVec<Height, T>,
indexes: &indexes::Vecs,
exit: &Exit,
) -> Result<()> {
let src_len = height_source.len();
let prev_height = starting_indexes.height.decremented().unwrap_or_default();
macro_rules! period {
($field:ident) => {
compute_period_extremum(
&mut self.0.$field,
starting_indexes.$field,
indexes.height.$field.collect_one(prev_height).unwrap_or_default(),
&indexes.$field.first_height,
height_source,
src_len,

View File

@@ -0,0 +1,32 @@
//! Generic 2-slot container for 1w + 1m EMA pairs.
use brk_traversable::Traversable;
#[derive(Clone, Traversable)]
pub struct Emas1w1m<A, B = A> {
#[traversable(rename = "1w")]
pub _1w: A,
#[traversable(rename = "1m")]
pub _1m: B,
}
impl<A> Emas1w1m<A> {
pub const SUFFIXES: [&'static str; 2] = ["ema_1w", "ema_1m"];
pub fn try_from_fn<E>(
mut f: impl FnMut(&str) -> std::result::Result<A, E>,
) -> std::result::Result<Self, E> {
Ok(Self {
_1w: f(Self::SUFFIXES[0])?,
_1m: f(Self::SUFFIXES[1])?,
})
}
pub fn as_array(&self) -> [&A; 2] {
[&self._1w, &self._1m]
}
pub fn as_mut_array(&mut self) -> [&mut A; 2] {
[&mut self._1w, &mut self._1m]
}
}

View File

@@ -0,0 +1,29 @@
//! Generic 1-slot container for 2w EMA.
use brk_traversable::Traversable;
#[derive(Clone, Traversable)]
pub struct Emas2w<A> {
#[traversable(rename = "2w")]
pub _2w: A,
}
impl<A> Emas2w<A> {
pub const SUFFIXES: [&'static str; 1] = ["ema_2w"];
pub fn try_from_fn<E>(
mut f: impl FnMut(&str) -> std::result::Result<A, E>,
) -> std::result::Result<Self, E> {
Ok(Self {
_2w: f(Self::SUFFIXES[0])?,
})
}
pub fn as_array(&self) -> [&A; 1] {
[&self._2w]
}
pub fn as_mut_array(&mut self) -> [&mut A; 1] {
[&mut self._2w]
}
}

View File

@@ -1,5 +1,5 @@
mod _1w_1m;
mod _2w;
mod emas_1w_1m;
mod emas_2w;
pub use _1w_1m::*;
pub use _2w::*;
pub use emas_1w_1m::*;
pub use emas_2w::*;

View File

@@ -29,16 +29,9 @@ impl RollingFullSlot {
) -> Result<Self> {
Ok(Self {
sum: ByUnit::forced_import(db, &format!("{name}_sum"), version, indexes)?,
distribution: DistributionStats {
average: ByUnit::forced_import(db, &format!("{name}_average"), version, indexes)?,
min: ByUnit::forced_import(db, &format!("{name}_min"), version, indexes)?,
max: ByUnit::forced_import(db, &format!("{name}_max"), version, indexes)?,
pct10: ByUnit::forced_import(db, &format!("{name}_p10"), version, indexes)?,
pct25: ByUnit::forced_import(db, &format!("{name}_p25"), version, indexes)?,
median: ByUnit::forced_import(db, &format!("{name}_median"), version, indexes)?,
pct75: ByUnit::forced_import(db, &format!("{name}_p75"), version, indexes)?,
pct90: ByUnit::forced_import(db, &format!("{name}_p90"), version, indexes)?,
},
distribution: DistributionStats::try_from_fn(|suffix| {
ByUnit::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
})?,
})
}
@@ -55,21 +48,19 @@ impl RollingFullSlot {
let d = &mut self.distribution;
compute_rolling_distribution_from_starts(
max_from, starts, sats_source,
&mut d.average.sats.height, &mut d.min.sats.height,
&mut d.max.sats.height, &mut d.pct10.sats.height,
&mut d.pct25.sats.height, &mut d.median.sats.height,
&mut d.pct75.sats.height, &mut d.pct90.sats.height, exit,
)?;
compute_rolling_distribution_from_starts(
max_from, starts, cents_source,
&mut d.average.cents.height, &mut d.min.cents.height,
&mut d.max.cents.height, &mut d.pct10.cents.height,
&mut d.pct25.cents.height, &mut d.median.cents.height,
&mut d.pct75.cents.height, &mut d.pct90.cents.height, exit,
)?;
macro_rules! compute_unit {
($unit:ident, $source:expr) => {
compute_rolling_distribution_from_starts(
max_from, starts, $source,
&mut d.average.$unit.height, &mut d.min.$unit.height,
&mut d.max.$unit.height, &mut d.pct10.$unit.height,
&mut d.pct25.$unit.height, &mut d.median.$unit.height,
&mut d.pct75.$unit.height, &mut d.pct90.$unit.height, exit,
)?
};
}
compute_unit!(sats, sats_source);
compute_unit!(cents, cents_source);
Ok(())
}

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, Version};
use brk_types::{Cents, Height, Indexes, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, indexes, prices};
use crate::{blocks, indexes, prices};
use super::{ComputedFromHeightRatio, ComputedFromHeightRatioExtension};
@@ -36,7 +36,7 @@ impl ComputedFromHeightRatioExtended {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
metric_price: &impl ReadableVec<Height, Cents>,
) -> Result<()> {

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{BasisPoints32, Cents, Height, StoredF32, Version};
use brk_types::{BasisPoints32, Cents, Height, Indexes, StoredF32, Version};
use vecdb::{AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex, WritableVec};
use crate::{
ComputeIndexes, blocks, indexes,
blocks, indexes,
internal::{ComputedFromHeightStdDevExtended, Price, TDigest},
};
@@ -104,7 +104,7 @@ impl ComputedFromHeightRatioExtension {
pub(crate) fn compute_rest(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
ratio_source: &impl ReadableVec<Height, StoredF32>,
) -> Result<()> {
@@ -182,14 +182,9 @@ impl ComputedFromHeightRatioExtension {
}
// Compute stddev at height level
self.ratio_sd
.compute_all(blocks, starting_indexes, exit, ratio_source)?;
self.ratio_sd_4y
.compute_all(blocks, starting_indexes, exit, ratio_source)?;
self.ratio_sd_2y
.compute_all(blocks, starting_indexes, exit, ratio_source)?;
self.ratio_sd_1y
.compute_all(blocks, starting_indexes, exit, ratio_source)?;
for sd in [&mut self.ratio_sd, &mut self.ratio_sd_4y, &mut self.ratio_sd_2y, &mut self.ratio_sd_1y] {
sd.compute_all(blocks, starting_indexes, exit, ratio_source)?;
}
Ok(())
}
@@ -197,7 +192,7 @@ impl ComputedFromHeightRatioExtension {
/// Compute cents ratio bands: cents_band = metric_price_cents * ratio_percentile
pub(crate) fn compute_cents_bands(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
metric_price: &impl ReadableVec<Height, Cents>,
exit: &Exit,
) -> Result<()> {
@@ -224,14 +219,9 @@ impl ComputedFromHeightRatioExtension {
compute_band!(ratio_pct1_price, &self.ratio_pct1.bps.height);
// Stddev cents bands
self.ratio_sd
.compute_cents_bands(starting_indexes, metric_price, exit)?;
self.ratio_sd_4y
.compute_cents_bands(starting_indexes, metric_price, exit)?;
self.ratio_sd_2y
.compute_cents_bands(starting_indexes, metric_price, exit)?;
self.ratio_sd_1y
.compute_cents_bands(starting_indexes, metric_price, exit)?;
for sd in [&mut self.ratio_sd, &mut self.ratio_sd_4y, &mut self.ratio_sd_2y, &mut self.ratio_sd_1y] {
sd.compute_cents_bands(starting_indexes, metric_price, exit)?;
}
Ok(())
}

View File

@@ -8,10 +8,10 @@ pub use price_extended::*;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{BasisPoints32, Cents, Height, StoredF32, Version};
use brk_types::{BasisPoints32, Cents, Height, Indexes, StoredF32, Version};
use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, indexes, internal::Bp32ToFloat};
use crate::{indexes, internal::Bp32ToFloat};
use super::{ComputedFromHeight, LazyFromHeight};
@@ -56,7 +56,7 @@ impl ComputedFromHeightRatio {
/// Compute ratio = close_price / metric_price at height level (both in cents)
pub(crate) fn compute_ratio(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
close_price: &impl ReadableVec<Height, Cents>,
metric_price: &impl ReadableVec<Height, Cents>,
exit: &Exit,

View File

@@ -1,11 +1,11 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, Version};
use brk_types::{Cents, Height, Indexes, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
use crate::internal::{ComputedFromHeight, Price};
use crate::{ComputeIndexes, blocks, indexes, prices};
use crate::{blocks, indexes, prices};
use super::ComputedFromHeightRatioExtended;
@@ -37,7 +37,7 @@ impl ComputedFromHeightPriceWithRatioExtended {
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
mut compute_price: F,
) -> Result<()>

View File

@@ -1,12 +1,12 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, StoredF32, Version};
use brk_types::{Cents, Height, Indexes, StoredF32, Version};
use vecdb::{
AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex,
WritableVec,
};
use crate::{ComputeIndexes, blocks, indexes};
use crate::{blocks, indexes};
use crate::internal::{ComputedFromHeight, Price};
@@ -110,7 +110,7 @@ impl ComputedFromHeightStdDevExtended {
pub(crate) fn compute_all(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
source: &impl ReadableVec<Height, StoredF32>,
) -> Result<()> {
@@ -123,7 +123,7 @@ impl ComputedFromHeightStdDevExtended {
pub(crate) fn compute_bands(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
sma_opt: Option<&impl ReadableVec<Height, StoredF32>>,
source: &impl ReadableVec<Height, StoredF32>,
@@ -202,7 +202,7 @@ impl ComputedFromHeightStdDevExtended {
/// Compute cents price bands: cents_band = metric_price_cents * band_ratio
pub(crate) fn compute_cents_bands(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
metric_price: &impl ReadableVec<Height, Cents>,
exit: &Exit,
) -> Result<()> {

View File

@@ -4,10 +4,10 @@ pub use extended::*;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, StoredF32, Version};
use brk_types::{Height, Indexes, StoredF32, Version};
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{ComputeIndexes, blocks, indexes};
use crate::{blocks, indexes};
use crate::internal::ComputedFromHeight;
@@ -57,7 +57,7 @@ impl ComputedFromHeightStdDev {
pub(crate) fn compute_all(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
source: &impl ReadableVec<Height, StoredF32>,
) -> Result<()> {

View File

@@ -6,12 +6,12 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_traversable::Traversable;
use brk_types::TxIndex;
use brk_types::{Indexes, TxIndex};
use schemars::JsonSchema;
use vecdb::{Database, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode, Version};
use crate::{
ComputeIndexes, indexes,
indexes,
internal::{ComputedVecValue, NumericValue, TxDerivedDistribution},
};
@@ -43,7 +43,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
skip_count: usize,
) -> Result<()>

View File

@@ -3,12 +3,12 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_traversable::Traversable;
use brk_types::TxIndex;
use brk_types::{Indexes, TxIndex};
use schemars::JsonSchema;
use vecdb::{Database, Exit, LazyVecFrom2, ReadableVec, Rw, StorageMode, Version};
use crate::{
ComputeIndexes, indexes,
indexes,
internal::{ComputedVecValue, NumericValue, TxDerivedDistribution},
};
@@ -47,7 +47,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()>
where

View File

@@ -13,14 +13,14 @@ use vecdb::{
use crate::{
indexes, indexes_from,
internal::{ComputedVecValue, Indexes, NumericValue},
internal::{ComputedVecValue, NumericValue, PerPeriod},
};
#[derive(Clone, Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct ComputedHeightDerived<T>(
#[allow(clippy::type_complexity)]
pub Indexes<
pub PerPeriod<
LazyAggVec<Minute10, Option<T>, Height, Height, T>,
LazyAggVec<Minute30, Option<T>, Height, Height, T>,
LazyAggVec<Hour1, Option<T>, Height, Height, T>,

View File

@@ -16,7 +16,7 @@ use vecdb::{
use crate::{
indexes, indexes_from,
internal::{
ComputedFromHeight, ComputedHeightDerived, ComputedVecValue, Indexes, NumericValue,
ComputedFromHeight, ComputedHeightDerived, ComputedVecValue, NumericValue, PerPeriod,
},
};
@@ -59,7 +59,7 @@ where
#[traversable(transparent)]
pub struct LazyHeightDerived<T, S1T = T>(
#[allow(clippy::type_complexity)]
pub Indexes<
pub PerPeriod<
LazyTransformLast<Minute10, Option<T>, Option<S1T>>,
LazyTransformLast<Minute30, Option<T>, Option<S1T>>,
LazyTransformLast<Hour1, Option<T>, Option<S1T>>,

View File

@@ -7,7 +7,7 @@ use brk_traversable::Traversable;
#[derive(Clone, Traversable)]
#[traversable(merge)]
pub struct Indexes<M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE, DE> {
pub struct PerPeriod<M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE, DE> {
pub minute10: M10,
pub minute30: M30,
pub hour1: H1,
@@ -25,7 +25,7 @@ pub struct Indexes<M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE
pub difficultyepoch: DE,
}
/// Helper macro to construct an `Indexes` by applying a macro to each field.
/// Helper macro to construct a `PerPeriod` by applying a macro to each field.
///
/// Usage:
/// ```ignore
@@ -35,7 +35,7 @@ pub struct Indexes<M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE
#[macro_export]
macro_rules! indexes_from {
($period:ident, $epoch:ident) => {
$crate::internal::Indexes {
$crate::internal::PerPeriod {
minute10: $period!(minute10),
minute30: $period!(minute30),
hour1: $period!(hour1),

View File

@@ -14,14 +14,14 @@ use vecdb::{LazyVecFrom1, ReadableCloneableVec, UnaryTransform};
use crate::{
indexes_from,
internal::{ComputedVecValue, EagerIndexes, Indexes},
internal::{ComputedVecValue, EagerIndexes, PerPeriod},
};
#[derive(Clone, Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct LazyEagerIndexes<T, S>(
#[allow(clippy::type_complexity)]
pub Indexes<
pub PerPeriod<
LazyVecFrom1<Minute10, T, Minute10, S>,
LazyVecFrom1<Minute30, T, Minute30, S>,
LazyVecFrom1<Hour1, T, Hour1, S>,

View File

@@ -37,16 +37,9 @@ where
indexes: &indexes::Vecs,
) -> Result<Self> {
let v = version + VERSION;
Ok(Self(DistributionStats {
average: RollingWindows::forced_import(db, &format!("{name}_average"), v, indexes)?,
min: RollingWindows::forced_import(db, &format!("{name}_min"), v, indexes)?,
max: RollingWindows::forced_import(db, &format!("{name}_max"), v, indexes)?,
pct10: RollingWindows::forced_import(db, &format!("{name}_p10"), v, indexes)?,
pct25: RollingWindows::forced_import(db, &format!("{name}_p25"), v, indexes)?,
median: RollingWindows::forced_import(db, &format!("{name}_median"), v, indexes)?,
pct75: RollingWindows::forced_import(db, &format!("{name}_p75"), v, indexes)?,
pct90: RollingWindows::forced_import(db, &format!("{name}_p90"), v, indexes)?,
}))
Ok(Self(DistributionStats::try_from_fn(|suffix| {
RollingWindows::forced_import(db, &format!("{name}_{suffix}"), v, indexes)
})?))
}
/// Compute all 8 distribution stats across all 4 windows from a single source.
@@ -66,34 +59,21 @@ where
T: Copy + Ord + From<f64> + Default,
f64: From<T>,
{
compute_rolling_distribution_from_starts(
max_from, windows._24h, source,
&mut self.0.average._24h.height, &mut self.0.min._24h.height,
&mut self.0.max._24h.height, &mut self.0.pct10._24h.height,
&mut self.0.pct25._24h.height, &mut self.0.median._24h.height,
&mut self.0.pct75._24h.height, &mut self.0.pct90._24h.height, exit,
)?;
compute_rolling_distribution_from_starts(
max_from, windows._1w, source,
&mut self.0.average._1w.height, &mut self.0.min._1w.height,
&mut self.0.max._1w.height, &mut self.0.pct10._1w.height,
&mut self.0.pct25._1w.height, &mut self.0.median._1w.height,
&mut self.0.pct75._1w.height, &mut self.0.pct90._1w.height, exit,
)?;
compute_rolling_distribution_from_starts(
max_from, windows._1m, source,
&mut self.0.average._1m.height, &mut self.0.min._1m.height,
&mut self.0.max._1m.height, &mut self.0.pct10._1m.height,
&mut self.0.pct25._1m.height, &mut self.0.median._1m.height,
&mut self.0.pct75._1m.height, &mut self.0.pct90._1m.height, exit,
)?;
compute_rolling_distribution_from_starts(
max_from, windows._1y, source,
&mut self.0.average._1y.height, &mut self.0.min._1y.height,
&mut self.0.max._1y.height, &mut self.0.pct10._1y.height,
&mut self.0.pct25._1y.height, &mut self.0.median._1y.height,
&mut self.0.pct75._1y.height, &mut self.0.pct90._1y.height, exit,
)?;
macro_rules! compute_window {
($w:ident) => {
compute_rolling_distribution_from_starts(
max_from, windows.$w, source,
&mut self.0.average.$w.height, &mut self.0.min.$w.height,
&mut self.0.max.$w.height, &mut self.0.pct10.$w.height,
&mut self.0.pct25.$w.height, &mut self.0.median.$w.height,
&mut self.0.pct75.$w.height, &mut self.0.pct90.$w.height, exit,
)?
};
}
compute_window!(_24h);
compute_window!(_1w);
compute_window!(_1m);
compute_window!(_1y);
Ok(())
}

View File

@@ -7,12 +7,12 @@ use brk_error::Result;
use brk_indexer::Indexer;
use brk_traversable::Traversable;
use brk_types::{Height, TxIndex};
use brk_types::{Height, Indexes, TxIndex};
use schemars::JsonSchema;
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode, Version};
use crate::{
ComputeIndexes, indexes,
indexes,
internal::{ComputedVecValue, Distribution, NumericValue},
};
@@ -66,7 +66,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
txindex_source: &impl ReadableVec<TxIndex, T>,
exit: &Exit,
) -> Result<()>
@@ -93,7 +93,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
txindex_source: &impl ReadableVec<TxIndex, T>,
exit: &Exit,
skip_count: usize,

View File

@@ -28,7 +28,6 @@ mod supply;
mod traits;
mod transactions;
use indexes::ComputeIndexes;
#[derive(Traversable)]
pub struct Computer<M: StorageMode = Rw> {

View File

@@ -1,16 +1,16 @@
use brk_error::Result;
use brk_types::{StoredF32, Timestamp};
use brk_types::{Indexes, StoredF32, Timestamp};
use vecdb::{Exit, ReadableVec, VecIndex};
use super::Vecs;
use crate::{blocks, ComputeIndexes, prices};
use crate::{blocks, prices};
impl Vecs {
pub(crate) fn compute(
&mut self,
prices: &prices::Vecs,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.price_ath.cents.height.compute_all_time_high(

View File

@@ -1,7 +1,8 @@
use brk_error::Result;
use brk_types::Indexes;
use vecdb::Exit;
use crate::{ComputeIndexes, blocks, distribution, indexes, mining, prices, transactions};
use crate::{blocks, distribution, indexes, mining, prices, transactions};
use super::Vecs;
@@ -15,7 +16,7 @@ impl Vecs {
mining: &mining::Vecs,
distribution: &distribution::Vecs,
transactions: &transactions::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.ath.compute(prices, blocks, starting_indexes, exit)?;

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_types::{BasisPointsSigned32, Bitcoin, Cents, Date, Day1, Dollars, Sats};
use brk_types::{BasisPointsSigned32, Bitcoin, Cents, Date, Day1, Dollars, Indexes, Sats};
use vecdb::{AnyVec, Exit, ReadableOptionVec, ReadableVec, VecIndex};
use super::Vecs;
use crate::{
ComputeIndexes, blocks, indexes, internal::RatioDiffCentsBps32, market::lookback, prices,
blocks, indexes, internal::RatioDiffCentsBps32, market::lookback, prices,
};
const DCA_AMOUNT: Dollars = Dollars::mint(100.0);
@@ -16,7 +16,7 @@ impl Vecs {
prices: &prices::Vecs,
blocks: &blocks::Vecs,
lookback: &lookback::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let h2d = &indexes.height.day1;

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_types::{BasisPoints16, Dollars};
use brk_types::{BasisPoints16, Dollars, Indexes};
use vecdb::Exit;
use super::{super::range, Vecs};
use crate::{
ComputeIndexes, blocks, distribution,
blocks, distribution,
internal::{RatioDollarsBp32, Windows},
mining, prices, transactions,
};
@@ -31,15 +31,17 @@ impl Vecs {
distribution: &distribution::Vecs,
transactions: &transactions::Vecs,
moving_average: &super::super::moving_average::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.puell_multiple.bps.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
starting_indexes.height,
&rewards.subsidy.base.usd.height,
&rewards.subsidy_sma_1y.usd.height,
exit,
)?;
self.puell_multiple
.bps
.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
starting_indexes.height,
&rewards.subsidy.base.usd.height,
&rewards.subsidy_sma_1y.usd.height,
exit,
)?;
// Stochastic Oscillator: K = (close - low_2w) / (high_2w - low_2w), stored as ratio (01)
{
@@ -54,7 +56,7 @@ impl Vecs {
let stoch = if range == 0.0 {
BasisPoints16::ZERO
} else {
BasisPoints16::from(((*close - *low) / range) as f64)
BasisPoints16::from((*close - *low) / range)
};
(h, stoch)
},
@@ -70,7 +72,8 @@ impl Vecs {
}
// RSI per timeframe
for (tf, rsi_chain) in Windows::<()>::SUFFIXES.into_iter()
for (tf, rsi_chain) in Windows::<()>::SUFFIXES
.into_iter()
.zip(self.rsi.as_mut_array())
{
let m = tf_multiplier(tf);
@@ -93,7 +96,8 @@ impl Vecs {
}
// MACD per timeframe
for (tf, macd_chain) in Windows::<()>::SUFFIXES.into_iter()
for (tf, macd_chain) in Windows::<()>::SUFFIXES
.into_iter()
.zip(self.macd.as_mut_array())
{
let m = tf_multiplier(tf);
@@ -110,28 +114,34 @@ impl Vecs {
}
// Gini (per height)
super::gini::compute(
&mut self.gini,
distribution,
starting_indexes,
exit,
)?;
super::gini::compute(&mut self.gini, distribution, starting_indexes, exit)?;
// NVT: market_cap / tx_volume_24h
self.nvt.bps.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
starting_indexes.height,
&distribution.utxo_cohorts.all.metrics.supply.total.usd.height,
&transactions.volume.sent_sum.rolling._24h.usd.height,
exit,
)?;
self.nvt
.bps
.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
starting_indexes.height,
&distribution
.utxo_cohorts
.all
.metrics
.supply
.total
.usd
.height,
&transactions.volume.sent_sum.rolling._24h.usd.height,
exit,
)?;
// Pi Cycle: sma_111d / sma_350d_x2
self.pi_cycle.bps.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
starting_indexes.height,
&moving_average.price_sma_111d.price.usd.height,
&moving_average.price_sma_350d_x2.usd.height,
exit,
)?;
self.pi_cycle
.bps
.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
starting_indexes.height,
&moving_average.price_sma_111d.price.usd.height,
&moving_average.price_sma_350d_x2.usd.height,
exit,
)?;
Ok(())
}

View File

@@ -1,13 +1,13 @@
use brk_error::Result;
use brk_types::{BasisPoints16, Sats, StoredU64, Version};
use brk_types::{BasisPoints16, Indexes, Sats, StoredU64, Version};
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableVec, VecIndex, WritableVec};
use crate::{ComputeIndexes, distribution, internal::PercentFromHeight};
use crate::{distribution, internal::PercentFromHeight};
pub(super) fn compute(
gini: &mut PercentFromHeight<BasisPoints16>,
distribution: &distribution::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let amount_range = &distribution.utxo_cohorts.amount_range;

View File

@@ -1,8 +1,9 @@
use brk_error::Result;
use brk_types::Indexes;
use vecdb::Exit;
use super::MacdChain;
use crate::{ComputeIndexes, blocks, prices};
use crate::{blocks, prices};
#[allow(clippy::too_many_arguments)]
pub(super) fn compute(
@@ -12,7 +13,7 @@ pub(super) fn compute(
fast_days: usize,
slow_days: usize,
signal_days: usize,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let close = &prices.price.usd.height;

View File

@@ -1,9 +1,9 @@
use brk_error::Result;
use brk_types::{BasisPoints16, Height, StoredF32};
use brk_types::{BasisPoints16, Height, Indexes, StoredF32};
use vecdb::{Exit, ReadableVec};
use super::RsiChain;
use crate::{ComputeIndexes, blocks};
use crate::blocks;
pub(super) fn compute(
chain: &mut RsiChain,
@@ -11,7 +11,7 @@ pub(super) fn compute(
returns_source: &impl ReadableVec<Height, StoredF32>,
rma_days: usize,
stoch_sma_days: usize,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let ws_rma = blocks.count.start_vec(rma_days);

View File

@@ -1,15 +1,16 @@
use brk_error::Result;
use brk_types::Indexes;
use vecdb::Exit;
use super::Vecs;
use crate::{blocks, ComputeIndexes, prices};
use crate::{blocks, prices};
impl Vecs {
pub(crate) fn compute(
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let price = &prices.price.cents.height;

View File

@@ -1,15 +1,16 @@
use brk_error::Result;
use brk_types::Indexes;
use vecdb::Exit;
use super::Vecs;
use crate::{ComputeIndexes, blocks, prices};
use crate::{blocks, prices};
impl Vecs {
pub(crate) fn compute(
&mut self,
blocks: &blocks::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let close = &prices.price.cents.height;

View File

@@ -1,16 +1,16 @@
use brk_error::Result;
use brk_types::{BasisPoints16, StoredF32};
use brk_types::{BasisPoints16, Indexes, StoredF32};
use vecdb::{Exit, ReadableVec, VecIndex};
use super::Vecs;
use crate::{blocks, ComputeIndexes, prices};
use crate::{blocks, prices};
impl Vecs {
pub(crate) fn compute(
&mut self,
prices: &prices::Vecs,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let price = &prices.price.cents.height;

View File

@@ -1,9 +1,9 @@
use brk_error::Result;
use brk_types::{BasisPointsSigned32, Dollars, StoredF32};
use brk_types::{BasisPointsSigned32, Dollars, Indexes, StoredF32};
use vecdb::Exit;
use super::Vecs;
use crate::{ComputeIndexes, blocks, internal::RatioDiffDollarsBps32, market::lookback, prices};
use crate::{blocks, internal::RatioDiffDollarsBps32, market::lookback, prices};
impl Vecs {
pub(crate) fn compute(
@@ -11,7 +11,7 @@ impl Vecs {
prices: &prices::Vecs,
blocks: &blocks::Vecs,
lookback: &lookback::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// Compute price returns at height level

View File

@@ -14,17 +14,50 @@ impl Vecs {
) -> Result<()> {
// Sharpe ratios: returns / volatility
for (out, ret, vol) in [
(&mut self.price_sharpe_1w, &returns.price_return._1w.ratio.height, &self.price_volatility_1w.height),
(&mut self.price_sharpe_1m, &returns.price_return._1m.ratio.height, &self.price_volatility_1m.height),
(&mut self.price_sharpe_1y, &returns.price_return._1y.ratio.height, &self.price_volatility_1y.height),
(
&mut self.price_sharpe_1w,
&returns.price_return._1w.ratio.height,
&self.price_volatility_1w.height,
),
(
&mut self.price_sharpe_1m,
&returns.price_return._1m.ratio.height,
&self.price_volatility_1m.height,
),
(
&mut self.price_sharpe_1y,
&returns.price_return._1y.ratio.height,
&self.price_volatility_1y.height,
),
] {
compute_ratio(&mut out.height, starting_indexes_height, ret, vol, exit)?;
}
// Sortino ratios: returns / downside volatility (sd * sqrt(days))
compute_sortino(&mut self.price_sortino_1w.height, starting_indexes_height, &returns.price_return._1w.ratio.height, &returns.price_downside_24h_sd_1w.sd.height, 7.0_f32.sqrt(), exit)?;
compute_sortino(&mut self.price_sortino_1m.height, starting_indexes_height, &returns.price_return._1m.ratio.height, &returns.price_downside_24h_sd_1m.sd.height, 30.0_f32.sqrt(), exit)?;
compute_sortino(&mut self.price_sortino_1y.height, starting_indexes_height, &returns.price_return._1y.ratio.height, &returns.price_downside_24h_sd_1y.sd.height, 365.0_f32.sqrt(), exit)?;
compute_sortino(
&mut self.price_sortino_1w.height,
starting_indexes_height,
&returns.price_return._1w.ratio.height,
&returns.price_downside_24h_sd_1w.sd.height,
7.0_f32.sqrt(),
exit,
)?;
compute_sortino(
&mut self.price_sortino_1m.height,
starting_indexes_height,
&returns.price_return._1m.ratio.height,
&returns.price_downside_24h_sd_1m.sd.height,
30.0_f32.sqrt(),
exit,
)?;
compute_sortino(
&mut self.price_sortino_1y.height,
starting_indexes_height,
&returns.price_return._1y.ratio.height,
&returns.price_downside_24h_sd_1y.sd.height,
365.0_f32.sqrt(),
exit,
)?;
Ok(())
}
@@ -63,8 +96,12 @@ fn compute_sortino(
ret,
sd,
|(h, ret, sd, ..)| {
let downside_vol = f32::from(*sd) * sqrt_days;
let ratio = if downside_vol == 0.0 { 0.0 } else { f32::from(*ret) / downside_vol };
let downside_vol = (*sd) * sqrt_days;
let ratio = if downside_vol == 0.0 {
0.0
} else {
(*ret) / downside_vol
};
(h, StoredF32::from(ratio))
},
exit,

View File

@@ -1,9 +1,10 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::Indexes;
use vecdb::Exit;
use super::Vecs;
use crate::{ComputeIndexes, blocks, indexes, prices, transactions};
use crate::{blocks, indexes, prices, transactions};
impl Vecs {
#[allow(clippy::too_many_arguments)]
@@ -14,7 +15,7 @@ impl Vecs {
blocks: &blocks::Vecs,
transactions: &transactions::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// Block rewards (coinbase, subsidy, fee_dominance, etc.)

View File

@@ -1,12 +1,11 @@
use brk_error::Result;
use brk_types::{Dollars, Height, Sats, StoredF32, StoredF64};
use brk_types::{Dollars, Height, Indexes, Sats, StoredF32, StoredF64};
use vecdb::{Exit, ReadableVec};
use super::Vecs;
use crate::{
blocks::{self, ONE_TERA_HASH, TARGET_BLOCKS_PER_DAY_F64},
internal::RatioDiffF32Bps32,
ComputeIndexes,
};
impl Vecs {
@@ -16,7 +15,7 @@ impl Vecs {
difficulty_vecs: &blocks::DifficultyVecs,
coinbase_sats_24h_sum: &impl ReadableVec<Height, Sats>,
coinbase_usd_24h_sum: &impl ReadableVec<Height, Dollars>,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.hash_rate.height.compute_transform2(

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{BasisPoints16, CheckedSub, HalvingEpoch, Sats};
use brk_types::{BasisPoints16, CheckedSub, HalvingEpoch, Indexes, Sats};
use vecdb::{Exit, ReadableVec, VecIndex};
use super::Vecs;
use crate::{ComputeIndexes, blocks, indexes, internal::RatioSatsBp16, prices, transactions};
use crate::{blocks, indexes, internal::RatioSatsBp16, prices, transactions};
impl Vecs {
#[allow(clippy::too_many_arguments)]
@@ -15,7 +15,7 @@ impl Vecs {
count_vecs: &blocks::CountVecs,
transactions_fees: &transactions::FeesVecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();

View File

@@ -1,9 +1,10 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::Indexes;
use vecdb::Exit;
use super::Vecs;
use crate::{ComputeIndexes, blocks, indexes, inputs, scripts};
use crate::{blocks, indexes, inputs, scripts};
impl Vecs {
#[allow(clippy::too_many_arguments)]
@@ -14,7 +15,7 @@ impl Vecs {
inputs: &inputs::Vecs,
scripts: &scripts::Vecs,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.spent

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Height, StoredU64};
use brk_types::{Height, Indexes, StoredU64};
use vecdb::Exit;
use super::Vecs;
use crate::{ComputeIndexes, blocks, indexes, inputs, scripts};
use crate::{blocks, indexes, inputs, scripts};
impl Vecs {
#[allow(clippy::too_many_arguments)]
@@ -15,7 +15,7 @@ impl Vecs {
inputs_count: &inputs::CountVecs,
scripts_count: &scripts::CountVecs,
blocks: &blocks::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = blocks.count.window_starts();

View File

@@ -1,13 +1,13 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Height, TxInIndex, TxOutIndex};
use brk_types::{Height, Indexes, TxInIndex, TxOutIndex};
use tracing::info;
use vecdb::{
AnyStoredVec, AnyVec, Database, Exit, WritableVec, ReadableVec, Stamp, VecIndex,
};
use super::Vecs;
use crate::{inputs, ComputeIndexes};
use crate::inputs;
const HEIGHT_BATCH: u32 = 10_000;
@@ -17,7 +17,7 @@ impl Vecs {
db: &Database,
indexer: &Indexer,
inputs: &inputs::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let target_height = indexer.vecs.blocks.blockhash.len();

View File

@@ -4,7 +4,7 @@ use brk_error::Result;
use brk_indexer::Indexer;
use brk_store::AnyStore;
use brk_traversable::Traversable;
use brk_types::{Address, AddressBytes, Height, OutputType, PoolSlug, Pools, TxOutIndex, pools};
use brk_types::{Address, AddressBytes, Height, Indexes, OutputType, PoolSlug, Pools, TxOutIndex, pools};
use rayon::prelude::*;
use vecdb::{
AnyStoredVec, AnyVec, BytesVec, Database, Exit, ImportableVec, PAGE_SIZE, ReadableVec, Rw,
@@ -15,7 +15,7 @@ mod vecs;
use crate::{
blocks,
indexes::{self, ComputeIndexes},
indexes,
mining, prices,
};
@@ -73,7 +73,7 @@ impl Vecs {
blocks: &blocks::Vecs,
prices: &prices::Vecs,
mining: &mining::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_(
@@ -98,7 +98,7 @@ impl Vecs {
blocks: &blocks::Vecs,
prices: &prices::Vecs,
mining: &mining::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_height_to_pool(indexer, indexes, starting_indexes, exit)?;
@@ -121,7 +121,7 @@ impl Vecs {
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.height_to_pool

View File

@@ -1,11 +1,11 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{BasisPoints16, Height, PoolSlug, StoredU32};
use brk_types::{BasisPoints16, Height, Indexes, PoolSlug, StoredU32};
use vecdb::{AnyVec, BinaryTransform, Database, Exit, ReadableVec, Rw, StorageMode, VecIndex, Version};
use crate::{
blocks,
indexes::{self, ComputeIndexes},
indexes,
internal::{
ComputedFromHeightCumulativeSum, ComputedFromHeight, MaskSats,
PercentFromHeight, PercentRollingWindows, RatioU32Bp16, RollingWindows,
@@ -83,7 +83,7 @@ impl Vecs {
#[allow(clippy::too_many_arguments)]
pub(crate) fn compute(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
height_to_pool: &impl ReadableVec<Height, PoolSlug>,
blocks: &blocks::Vecs,
prices: &prices::Vecs,

View File

@@ -4,13 +4,12 @@ use brk_error::Result;
use brk_indexer::Indexer;
use brk_reader::Reader;
use brk_traversable::Traversable;
use brk_types::{BlkPosition, Height, TxIndex, Version};
use brk_types::{BlkPosition, Height, Indexes, TxIndex, Version};
use vecdb::{
AnyStoredVec, AnyVec, Database, Exit, WritableVec, ImportableVec, PAGE_SIZE, PcoVec,
ReadableVec, Rw, StorageMode, VecIndex,
};
use super::ComputeIndexes;
pub const DB_NAME: &str = "positions";
@@ -49,7 +48,7 @@ impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
reader: &Reader,
exit: &Exit,
) -> Result<()> {
@@ -62,7 +61,7 @@ impl Vecs {
fn compute_(
&mut self,
indexer: &Indexer,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
parser: &Reader,
exit: &Exit,
) -> Result<()> {

View File

@@ -3,19 +3,19 @@ use std::ops::Range;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_oracle::{Config, NUM_BINS, Oracle, START_HEIGHT, bin_to_cents, cents_to_bin};
use brk_types::{Cents, OutputType, Sats, TxIndex, TxOutIndex};
use brk_types::{Cents, Indexes, OutputType, Sats, TxIndex, TxOutIndex};
use tracing::info;
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableVec, StorageMode, VecIndex, WritableVec};
use super::Vecs;
use crate::{ComputeIndexes, indexes};
use crate::indexes;
impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_prices(indexer, starting_indexes, exit)?;
@@ -33,6 +33,7 @@ impl Vecs {
.compute_min(starting_indexes, &self.price.cents.height, indexes, exit)?;
self.ohlc.cents.compute_from_split(
starting_indexes,
indexes,
&self.split.open.cents,
&self.split.high.cents,
&self.split.low.cents,
@@ -48,7 +49,7 @@ impl Vecs {
fn compute_prices(
&mut self,
indexer: &Indexer,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let source_version =

View File

@@ -1,9 +1,9 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{
Cents, Close, Day1, Day3, DifficultyEpoch, HalvingEpoch, High, Hour1, Hour4, Hour12, Low,
Minute10, Minute30, Month1, Month3, Month6, OHLCCents, Open, Version, Week1,
Year1, Year10,
Cents, Close, Day1, Day3, DifficultyEpoch, HalvingEpoch, High, Hour1, Hour4, Hour12, Indexes,
Low, Minute10, Minute30, Month1, Month3, Month6, OHLCCents, Open, Version, Week1, Year1,
Year10,
};
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
@@ -14,8 +14,8 @@ use vecdb::{
};
use crate::{
ComputeIndexes, indexes_apply, indexes_from,
internal::{ComputedHeightDerived, EagerIndexes, Indexes},
indexes, indexes_apply, indexes_from,
internal::{ComputedHeightDerived, EagerIndexes, PerPeriod},
};
// ── EagerOhlcIndexes ─────────────────────────────────────────────────
@@ -24,7 +24,7 @@ use crate::{
#[traversable(merge)]
pub struct OhlcVecs<T, M: StorageMode = Rw>(
#[allow(clippy::type_complexity)]
pub Indexes<
pub PerPeriod<
<M as StorageMode>::Stored<EagerVec<BytesVec<Minute10, T>>>,
<M as StorageMode>::Stored<EagerVec<BytesVec<Minute30, T>>>,
<M as StorageMode>::Stored<EagerVec<BytesVec<Hour1, T>>>,
@@ -65,19 +65,27 @@ where
}
impl OhlcVecs<OHLCCents> {
#[allow(clippy::too_many_arguments)]
pub(crate) fn compute_from_split(
&mut self,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
indexes: &indexes::Vecs,
open: &EagerIndexes<Cents>,
high: &EagerIndexes<Cents>,
low: &EagerIndexes<Cents>,
close: &ComputedHeightDerived<Cents>,
exit: &Exit,
) -> Result<()> {
let prev_height = starting_indexes.height.decremented().unwrap_or_default();
macro_rules! period {
($field:ident) => {
self.0.$field.compute_transform4(
starting_indexes.$field,
indexes
.height
.$field
.collect_one(prev_height)
.unwrap_or_default(),
&open.$field,
&high.$field,
&low.$field,
@@ -94,9 +102,8 @@ impl OhlcVecs<OHLCCents> {
}
} else {
// Empty period (no blocks): flat candle at previous close
let prev_close = Close::new(
this.collect_last().map_or(o, |prev| *prev.close),
);
let prev_close =
Close::new(this.collect_last().map_or(o, |prev| *prev.close));
OHLCCents::from(prev_close)
},
)
@@ -109,7 +116,11 @@ impl OhlcVecs<OHLCCents> {
macro_rules! epoch {
($field:ident) => {
self.0.$field.compute_transform4(
starting_indexes.$field,
indexes
.height
.$field
.collect_one(prev_height)
.unwrap_or_default(),
&open.$field,
&high.$field,
&low.$field,
@@ -142,7 +153,7 @@ impl OhlcVecs<OHLCCents> {
#[traversable(merge)]
pub struct LazyOhlcVecs<T, S>(
#[allow(clippy::type_complexity)]
pub Indexes<
pub PerPeriod<
LazyVecFrom1<Minute10, T, Minute10, S>,
LazyVecFrom1<Minute30, T, Minute30, S>,
LazyVecFrom1<Hour1, T, Hour1, S>,

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{BasisPoints16, Version};
use brk_types::{BasisPoints16, Indexes, Version};
use vecdb::{Database, Exit, Rw, StorageMode};
use crate::{
ComputeIndexes, indexes,
indexes,
internal::{PercentFromHeight, RatioU64Bp16},
outputs,
};
@@ -43,7 +43,7 @@ impl Vecs {
&mut self,
count: &CountVecs,
outputs_count: &outputs::CountVecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.taproot.compute_binary::<_, _, RatioU64Bp16>(

View File

@@ -1,8 +1,9 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::Indexes;
use vecdb::Exit;
use crate::{blocks, outputs, prices, ComputeIndexes};
use crate::{blocks, outputs, prices};
use super::Vecs;
@@ -13,7 +14,7 @@ impl Vecs {
blocks: &blocks::Vecs,
outputs: &outputs::Vecs,
prices: &prices::Vecs,
starting_indexes: &ComputeIndexes,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.count

Some files were not shown because too many files have changed in this diff Show More