mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
computer: snapshot
This commit is contained in:
36
crates/brk_computer/examples/tree.rs
Normal file
36
crates/brk_computer/examples/tree.rs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
use std::{env, fs, path::Path};
|
||||||
|
|
||||||
|
use brk_computer::Computer;
|
||||||
|
use brk_indexer::Indexer;
|
||||||
|
use brk_traversable::{Traversable, TreeNode};
|
||||||
|
|
||||||
|
pub fn main() -> color_eyre::Result<()> {
|
||||||
|
color_eyre::install()?;
|
||||||
|
|
||||||
|
let tmp = env::temp_dir().join("brk_tree_gen");
|
||||||
|
fs::create_dir_all(&tmp)?;
|
||||||
|
|
||||||
|
let indexer = Indexer::forced_import(&tmp)?;
|
||||||
|
let computer = Computer::forced_import(&tmp, &indexer)?;
|
||||||
|
|
||||||
|
let tree = TreeNode::Branch(
|
||||||
|
[
|
||||||
|
("indexed".to_string(), indexer.vecs.to_tree_node()),
|
||||||
|
("computed".to_string(), computer.to_tree_node()),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
.merge_branches()
|
||||||
|
.expect("Tree merge failed");
|
||||||
|
|
||||||
|
let json = serde_json::to_string_pretty(&tree)?;
|
||||||
|
|
||||||
|
let out_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("tree.json");
|
||||||
|
fs::write(&out_path, &json)?;
|
||||||
|
eprintln!("Wrote {} bytes to {}", json.len(), out_path.display());
|
||||||
|
|
||||||
|
fs::remove_dir_all(&tmp)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -18,14 +18,16 @@ impl Vecs {
|
|||||||
self.time
|
self.time
|
||||||
.timestamp
|
.timestamp
|
||||||
.compute(indexer, indexes, starting_indexes, exit)?;
|
.compute(indexer, indexes, starting_indexes, exit)?;
|
||||||
|
self.lookback
|
||||||
|
.compute(&self.time, starting_indexes, exit)?;
|
||||||
self.count
|
self.count
|
||||||
.compute(indexer, &self.time, starting_indexes, exit)?;
|
.compute(indexer, &self.lookback, starting_indexes, exit)?;
|
||||||
self.interval
|
self.interval
|
||||||
.compute(indexer, &self.count, starting_indexes, exit)?;
|
.compute(indexer, &self.lookback, starting_indexes, exit)?;
|
||||||
self.size
|
self.size
|
||||||
.compute(indexer, &self.count, starting_indexes, exit)?;
|
.compute(indexer, &self.lookback, starting_indexes, exit)?;
|
||||||
self.weight
|
self.weight
|
||||||
.compute(indexer, &self.count, starting_indexes, exit)?;
|
.compute(indexer, &self.lookback, starting_indexes, exit)?;
|
||||||
self.difficulty
|
self.difficulty
|
||||||
.compute(indexer, indexes, starting_indexes, exit)?;
|
.compute(indexer, indexes, starting_indexes, exit)?;
|
||||||
self.halving.compute(indexes, starting_indexes, exit)?;
|
self.halving.compute(indexes, starting_indexes, exit)?;
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_indexer::Indexer;
|
use brk_indexer::Indexer;
|
||||||
use brk_types::{Height, Indexes, StoredU32, Timestamp};
|
use brk_types::{Indexes, StoredU32};
|
||||||
use vecdb::{AnyVec, Cursor, EagerVec, Exit, PcoVec, ReadableVec, VecIndex};
|
use vecdb::Exit;
|
||||||
|
|
||||||
use crate::internal::WindowStarts;
|
use super::Vecs;
|
||||||
|
|
||||||
use super::{super::time, Vecs};
|
use crate::blocks::lookback;
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
indexer: &Indexer,
|
indexer: &Indexer,
|
||||||
time: &time::Vecs,
|
lookback: &lookback::Vecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Block count height + cumulative first (rolling computed after window starts)
|
// Block count height + cumulative
|
||||||
self.block_count.height.compute_range(
|
self.block_count.height.compute_range(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&indexer.vecs.blocks.weight,
|
&indexer.vecs.blocks.weight,
|
||||||
@@ -28,162 +28,15 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Compute rolling window starts
|
// Rolling window block counts
|
||||||
self.compute_rolling_start_hours(time, starting_indexes, exit, 1, |s| {
|
let ws = lookback.window_starts();
|
||||||
&mut s.height_1h_ago
|
|
||||||
})?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 1, |s| &mut s.height_24h_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 3, |s| &mut s.height_3d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 7, |s| &mut s.height_1w_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 8, |s| &mut s.height_8d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 9, |s| &mut s.height_9d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 12, |s| &mut s.height_12d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 13, |s| &mut s.height_13d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 14, |s| &mut s.height_2w_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 21, |s| &mut s.height_21d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 26, |s| &mut s.height_26d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 30, |s| &mut s.height_1m_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 34, |s| &mut s.height_34d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 55, |s| &mut s.height_55d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 60, |s| &mut s.height_2m_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 63, |s| &mut s.height_9w_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 84, |s| &mut s.height_12w_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 89, |s| &mut s.height_89d_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 90, |s| &mut s.height_3m_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 98, |s| &mut s.height_14w_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 111, |s| {
|
|
||||||
&mut s.height_111d_ago
|
|
||||||
})?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 144, |s| {
|
|
||||||
&mut s.height_144d_ago
|
|
||||||
})?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 180, |s| &mut s.height_6m_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 182, |s| &mut s.height_26w_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 200, |s| {
|
|
||||||
&mut s.height_200d_ago
|
|
||||||
})?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 270, |s| &mut s.height_9m_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 350, |s| {
|
|
||||||
&mut s.height_350d_ago
|
|
||||||
})?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 360, |s| &mut s.height_12m_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 365, |s| &mut s.height_1y_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 420, |s| &mut s.height_14m_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 730, |s| &mut s.height_2y_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 780, |s| &mut s.height_26m_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 1095, |s| &mut s.height_3y_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 1400, |s| {
|
|
||||||
&mut s.height_200w_ago
|
|
||||||
})?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 1460, |s| &mut s.height_4y_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 1825, |s| &mut s.height_5y_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 2190, |s| &mut s.height_6y_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 2920, |s| &mut s.height_8y_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 3285, |s| &mut s.height_9y_ago)?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 3650, |s| {
|
|
||||||
&mut s.height_10y_ago
|
|
||||||
})?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 4380, |s| {
|
|
||||||
&mut s.height_12y_ago
|
|
||||||
})?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 5110, |s| {
|
|
||||||
&mut s.height_14y_ago
|
|
||||||
})?;
|
|
||||||
self.compute_rolling_start(time, starting_indexes, exit, 9490, |s| {
|
|
||||||
&mut s.height_26y_ago
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Compute rolling window block counts (both block_count's own rolling + separate block_count_sum)
|
|
||||||
let ws = WindowStarts {
|
|
||||||
_24h: &self.height_24h_ago,
|
|
||||||
_1w: &self.height_1w_ago,
|
|
||||||
_1m: &self.height_1m_ago,
|
|
||||||
_1y: &self.height_1y_ago,
|
|
||||||
};
|
|
||||||
self.block_count.sum.compute_rolling_sum(
|
self.block_count.sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&ws,
|
&ws,
|
||||||
&self.block_count.height,
|
&self.block_count.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.block_count_sum.compute_rolling_sum(
|
|
||||||
starting_indexes.height,
|
|
||||||
&ws,
|
|
||||||
&self.block_count.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_rolling_start<F>(
|
|
||||||
&mut self,
|
|
||||||
time: &time::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
days: usize,
|
|
||||||
get_field: F,
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
|
|
||||||
{
|
|
||||||
self.compute_rolling_start_inner(time, starting_indexes, exit, get_field, |t, prev_ts| {
|
|
||||||
t.difference_in_days_between(prev_ts) >= days
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_rolling_start_hours<F>(
|
|
||||||
&mut self,
|
|
||||||
time: &time::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
hours: usize,
|
|
||||||
get_field: F,
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
|
|
||||||
{
|
|
||||||
self.compute_rolling_start_inner(time, starting_indexes, exit, get_field, |t, prev_ts| {
|
|
||||||
t.difference_in_hours_between(prev_ts) >= hours
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_rolling_start_inner<F, D>(
|
|
||||||
&mut self,
|
|
||||||
time: &time::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
get_field: F,
|
|
||||||
expired: D,
|
|
||||||
) -> Result<()>
|
|
||||||
where
|
|
||||||
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
|
|
||||||
D: Fn(Timestamp, Timestamp) -> bool,
|
|
||||||
{
|
|
||||||
let field = get_field(self);
|
|
||||||
let resume_from = field.len().min(starting_indexes.height.to_usize());
|
|
||||||
let mut prev = if resume_from > 0 {
|
|
||||||
field.collect_one_at(resume_from - 1).unwrap()
|
|
||||||
} else {
|
|
||||||
Height::ZERO
|
|
||||||
};
|
|
||||||
let mut cursor = Cursor::new(&time.timestamp_monotonic);
|
|
||||||
cursor.advance(prev.to_usize());
|
|
||||||
let mut prev_ts = cursor.next().unwrap();
|
|
||||||
Ok(field.compute_transform(
|
|
||||||
starting_indexes.height,
|
|
||||||
&time.timestamp_monotonic,
|
|
||||||
|(h, t, ..)| {
|
|
||||||
while expired(t, prev_ts) {
|
|
||||||
prev.increment();
|
|
||||||
prev_ts = cursor.next().unwrap();
|
|
||||||
if prev > h {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(h, prev)
|
|
||||||
},
|
|
||||||
exit,
|
|
||||||
)?)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_types::Version;
|
use brk_types::Version;
|
||||||
use vecdb::{Database, ImportableVec};
|
use vecdb::Database;
|
||||||
|
|
||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{BlockCountTarget, ComputedFromHeightCumulativeSum, ConstantVecs, RollingWindows},
|
internal::{BlockCountTarget, ComputedFromHeightCumulativeSum, ConstantVecs},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
@@ -26,55 +26,6 @@ impl Vecs {
|
|||||||
version,
|
version,
|
||||||
indexes,
|
indexes,
|
||||||
)?,
|
)?,
|
||||||
height_1h_ago: ImportableVec::forced_import(db, "height_1h_ago", version)?,
|
|
||||||
height_24h_ago: ImportableVec::forced_import(db, "height_24h_ago", version)?,
|
|
||||||
height_3d_ago: ImportableVec::forced_import(db, "height_3d_ago", version)?,
|
|
||||||
height_1w_ago: ImportableVec::forced_import(db, "height_1w_ago", version)?,
|
|
||||||
height_8d_ago: ImportableVec::forced_import(db, "height_8d_ago", version)?,
|
|
||||||
height_9d_ago: ImportableVec::forced_import(db, "height_9d_ago", version)?,
|
|
||||||
height_12d_ago: ImportableVec::forced_import(db, "height_12d_ago", version)?,
|
|
||||||
height_13d_ago: ImportableVec::forced_import(db, "height_13d_ago", version)?,
|
|
||||||
height_2w_ago: ImportableVec::forced_import(db, "height_2w_ago", version)?,
|
|
||||||
height_21d_ago: ImportableVec::forced_import(db, "height_21d_ago", version)?,
|
|
||||||
height_26d_ago: ImportableVec::forced_import(db, "height_26d_ago", version)?,
|
|
||||||
height_1m_ago: ImportableVec::forced_import(db, "height_1m_ago", version)?,
|
|
||||||
height_34d_ago: ImportableVec::forced_import(db, "height_34d_ago", version)?,
|
|
||||||
height_55d_ago: ImportableVec::forced_import(db, "height_55d_ago", version)?,
|
|
||||||
height_2m_ago: ImportableVec::forced_import(db, "height_2m_ago", version)?,
|
|
||||||
height_9w_ago: ImportableVec::forced_import(db, "height_9w_ago", version)?,
|
|
||||||
height_12w_ago: ImportableVec::forced_import(db, "height_12w_ago", version)?,
|
|
||||||
height_89d_ago: ImportableVec::forced_import(db, "height_89d_ago", version)?,
|
|
||||||
height_3m_ago: ImportableVec::forced_import(db, "height_3m_ago", version)?,
|
|
||||||
height_14w_ago: ImportableVec::forced_import(db, "height_14w_ago", version)?,
|
|
||||||
height_111d_ago: ImportableVec::forced_import(db, "height_111d_ago", version)?,
|
|
||||||
height_144d_ago: ImportableVec::forced_import(db, "height_144d_ago", version)?,
|
|
||||||
height_6m_ago: ImportableVec::forced_import(db, "height_6m_ago", version)?,
|
|
||||||
height_26w_ago: ImportableVec::forced_import(db, "height_26w_ago", version)?,
|
|
||||||
height_200d_ago: ImportableVec::forced_import(db, "height_200d_ago", version)?,
|
|
||||||
height_9m_ago: ImportableVec::forced_import(db, "height_9m_ago", version)?,
|
|
||||||
height_350d_ago: ImportableVec::forced_import(db, "height_350d_ago", version)?,
|
|
||||||
height_12m_ago: ImportableVec::forced_import(db, "height_12m_ago", version)?,
|
|
||||||
height_1y_ago: ImportableVec::forced_import(db, "height_1y_ago", version)?,
|
|
||||||
height_14m_ago: ImportableVec::forced_import(db, "height_14m_ago", version)?,
|
|
||||||
height_2y_ago: ImportableVec::forced_import(db, "height_2y_ago", version)?,
|
|
||||||
height_26m_ago: ImportableVec::forced_import(db, "height_26m_ago", version)?,
|
|
||||||
height_3y_ago: ImportableVec::forced_import(db, "height_3y_ago", version)?,
|
|
||||||
height_200w_ago: ImportableVec::forced_import(db, "height_200w_ago", version)?,
|
|
||||||
height_4y_ago: ImportableVec::forced_import(db, "height_4y_ago", version)?,
|
|
||||||
height_5y_ago: ImportableVec::forced_import(db, "height_5y_ago", version)?,
|
|
||||||
height_6y_ago: ImportableVec::forced_import(db, "height_6y_ago", version)?,
|
|
||||||
height_8y_ago: ImportableVec::forced_import(db, "height_8y_ago", version)?,
|
|
||||||
height_9y_ago: ImportableVec::forced_import(db, "height_9y_ago", version)?,
|
|
||||||
height_10y_ago: ImportableVec::forced_import(db, "height_10y_ago", version)?,
|
|
||||||
height_12y_ago: ImportableVec::forced_import(db, "height_12y_ago", version)?,
|
|
||||||
height_14y_ago: ImportableVec::forced_import(db, "height_14y_ago", version)?,
|
|
||||||
height_26y_ago: ImportableVec::forced_import(db, "height_26y_ago", version)?,
|
|
||||||
block_count_sum: RollingWindows::forced_import(
|
|
||||||
db,
|
|
||||||
"block_count_sum",
|
|
||||||
version,
|
|
||||||
indexes,
|
|
||||||
)?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,117 +1,11 @@
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Height, StoredU32, StoredU64};
|
use brk_types::{StoredU32, StoredU64};
|
||||||
use vecdb::{EagerVec, PcoVec, Rw, StorageMode};
|
use vecdb::{Rw, StorageMode};
|
||||||
|
|
||||||
use crate::internal::{
|
use crate::internal::{ComputedFromHeightCumulativeSum, ConstantVecs};
|
||||||
ComputedFromHeightCumulativeSum, ConstantVecs, RollingWindows, WindowStarts,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
pub block_count_target: ConstantVecs<StoredU64>,
|
pub block_count_target: ConstantVecs<StoredU64>,
|
||||||
pub block_count: ComputedFromHeightCumulativeSum<StoredU32, M>,
|
pub block_count: ComputedFromHeightCumulativeSum<StoredU32, M>,
|
||||||
pub block_count_sum: RollingWindows<StoredU32, M>,
|
|
||||||
|
|
||||||
pub height_1h_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_24h_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1d
|
|
||||||
pub height_3d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_1w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 7d
|
|
||||||
pub height_8d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_9d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_12d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_13d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_2w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 14d
|
|
||||||
pub height_21d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_26d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_1m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 30d
|
|
||||||
pub height_34d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_55d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_2m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 60d
|
|
||||||
pub height_9w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 63d
|
|
||||||
pub height_12w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 84d
|
|
||||||
pub height_89d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_3m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 90d
|
|
||||||
pub height_14w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 98d
|
|
||||||
pub height_111d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_144d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_6m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 180d
|
|
||||||
pub height_26w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 182d
|
|
||||||
pub height_200d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_9m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 270d
|
|
||||||
pub height_350d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
|
||||||
pub height_12m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 360d
|
|
||||||
pub height_1y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 365d
|
|
||||||
pub height_14m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 420d
|
|
||||||
pub height_2y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 730d
|
|
||||||
pub height_26m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 780d
|
|
||||||
pub height_3y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1095d
|
|
||||||
pub height_200w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1400d
|
|
||||||
pub height_4y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1460d
|
|
||||||
pub height_5y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1825d
|
|
||||||
pub height_6y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2190d
|
|
||||||
pub height_8y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2920d
|
|
||||||
pub height_9y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3285d
|
|
||||||
pub height_10y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3650d
|
|
||||||
pub height_12y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 4380d
|
|
||||||
pub height_14y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 5110d
|
|
||||||
pub height_26y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 9490d
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Vecs {
|
|
||||||
pub fn window_starts(&self) -> WindowStarts<'_> {
|
|
||||||
WindowStarts {
|
|
||||||
_24h: &self.height_24h_ago,
|
|
||||||
_1w: &self.height_1w_ago,
|
|
||||||
_1m: &self.height_1m_ago,
|
|
||||||
_1y: &self.height_1y_ago,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn start_vec(&self, days: usize) -> &EagerVec<PcoVec<Height, Height>> {
|
|
||||||
match days {
|
|
||||||
1 => &self.height_24h_ago,
|
|
||||||
3 => &self.height_3d_ago,
|
|
||||||
7 => &self.height_1w_ago,
|
|
||||||
8 => &self.height_8d_ago,
|
|
||||||
9 => &self.height_9d_ago,
|
|
||||||
12 => &self.height_12d_ago,
|
|
||||||
13 => &self.height_13d_ago,
|
|
||||||
14 => &self.height_2w_ago,
|
|
||||||
21 => &self.height_21d_ago,
|
|
||||||
26 => &self.height_26d_ago,
|
|
||||||
30 => &self.height_1m_ago,
|
|
||||||
34 => &self.height_34d_ago,
|
|
||||||
55 => &self.height_55d_ago,
|
|
||||||
60 => &self.height_2m_ago,
|
|
||||||
63 => &self.height_9w_ago,
|
|
||||||
84 => &self.height_12w_ago,
|
|
||||||
89 => &self.height_89d_ago,
|
|
||||||
90 => &self.height_3m_ago,
|
|
||||||
98 => &self.height_14w_ago,
|
|
||||||
111 => &self.height_111d_ago,
|
|
||||||
144 => &self.height_144d_ago,
|
|
||||||
180 => &self.height_6m_ago,
|
|
||||||
182 => &self.height_26w_ago,
|
|
||||||
200 => &self.height_200d_ago,
|
|
||||||
270 => &self.height_9m_ago,
|
|
||||||
350 => &self.height_350d_ago,
|
|
||||||
360 => &self.height_12m_ago,
|
|
||||||
365 => &self.height_1y_ago,
|
|
||||||
420 => &self.height_14m_ago,
|
|
||||||
730 => &self.height_2y_ago,
|
|
||||||
780 => &self.height_26m_ago,
|
|
||||||
1095 => &self.height_3y_ago,
|
|
||||||
1400 => &self.height_200w_ago,
|
|
||||||
1460 => &self.height_4y_ago,
|
|
||||||
1825 => &self.height_5y_ago,
|
|
||||||
2190 => &self.height_6y_ago,
|
|
||||||
2920 => &self.height_8y_ago,
|
|
||||||
3285 => &self.height_9y_ago,
|
|
||||||
3650 => &self.height_10y_ago,
|
|
||||||
4380 => &self.height_12y_ago,
|
|
||||||
5110 => &self.height_14y_ago,
|
|
||||||
9490 => &self.height_26y_ago,
|
|
||||||
_ => panic!("No start vec for {days} days"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
CountVecs, DifficultyVecs, HalvingVecs, IntervalVecs, SizeVecs, TimeVecs, Vecs, WeightVecs,
|
CountVecs, DifficultyVecs, HalvingVecs, IntervalVecs, LookbackVecs, SizeVecs, TimeVecs, Vecs,
|
||||||
|
WeightVecs,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
@@ -24,6 +25,7 @@ impl Vecs {
|
|||||||
let version = parent_version;
|
let version = parent_version;
|
||||||
|
|
||||||
let count = CountVecs::forced_import(&db, version, indexes)?;
|
let count = CountVecs::forced_import(&db, version, indexes)?;
|
||||||
|
let lookback = LookbackVecs::forced_import(&db, version)?;
|
||||||
let interval = IntervalVecs::forced_import(&db, version, indexes)?;
|
let interval = IntervalVecs::forced_import(&db, version, indexes)?;
|
||||||
let size = SizeVecs::forced_import(&db, version, indexes)?;
|
let size = SizeVecs::forced_import(&db, version, indexes)?;
|
||||||
let weight = WeightVecs::forced_import(&db, version, indexes)?;
|
let weight = WeightVecs::forced_import(&db, version, indexes)?;
|
||||||
@@ -34,6 +36,7 @@ impl Vecs {
|
|||||||
let this = Self {
|
let this = Self {
|
||||||
db,
|
db,
|
||||||
count,
|
count,
|
||||||
|
lookback,
|
||||||
interval,
|
interval,
|
||||||
size,
|
size,
|
||||||
weight,
|
weight,
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ impl Vecs {
|
|||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
indexer: &Indexer,
|
indexer: &Indexer,
|
||||||
count_vecs: &blocks::CountVecs,
|
lookback: &blocks::LookbackVecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut prev_timestamp = None;
|
let mut prev_timestamp = None;
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = lookback.window_starts();
|
||||||
self.0
|
self.0
|
||||||
.compute(starting_indexes.height, &window_starts, exit, |vec| {
|
.compute(starting_indexes.height, &window_starts, exit, |vec| {
|
||||||
vec.compute_transform(
|
vec.compute_transform(
|
||||||
|
|||||||
306
crates/brk_computer/src/blocks/lookback.rs
Normal file
306
crates/brk_computer/src/blocks/lookback.rs
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{Height, Indexes, Timestamp, Version};
|
||||||
|
use vecdb::{AnyVec, Cursor, Database, EagerVec, Exit, ImportableVec, PcoVec, ReadableVec, Rw, StorageMode, VecIndex};
|
||||||
|
|
||||||
|
use crate::internal::WindowStarts;
|
||||||
|
|
||||||
|
use super::time;
|
||||||
|
|
||||||
|
#[derive(Traversable)]
|
||||||
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
|
pub height_1h_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_24h_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1d
|
||||||
|
pub height_3d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_1w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 7d
|
||||||
|
pub height_8d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_9d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_12d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_13d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_2w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 14d
|
||||||
|
pub height_21d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_26d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_1m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 30d
|
||||||
|
pub height_34d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_55d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_2m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 60d
|
||||||
|
pub height_9w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 63d
|
||||||
|
pub height_12w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 84d
|
||||||
|
pub height_89d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_3m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 90d
|
||||||
|
pub height_14w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 98d
|
||||||
|
pub height_111d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_144d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_6m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 180d
|
||||||
|
pub height_26w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 182d
|
||||||
|
pub height_200d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_9m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 270d
|
||||||
|
pub height_350d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||||
|
pub height_12m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 360d
|
||||||
|
pub height_1y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 365d
|
||||||
|
pub height_14m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 420d
|
||||||
|
pub height_2y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 730d
|
||||||
|
pub height_26m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 780d
|
||||||
|
pub height_3y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1095d
|
||||||
|
pub height_200w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1400d
|
||||||
|
pub height_4y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1460d
|
||||||
|
pub height_5y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1825d
|
||||||
|
pub height_6y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2190d
|
||||||
|
pub height_8y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2920d
|
||||||
|
pub height_9y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3285d
|
||||||
|
pub height_10y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3650d
|
||||||
|
pub height_12y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 4380d
|
||||||
|
pub height_14y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 5110d
|
||||||
|
pub height_26y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 9490d
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vecs {
|
||||||
|
pub(crate) fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
height_1h_ago: ImportableVec::forced_import(db, "height_1h_ago", version)?,
|
||||||
|
height_24h_ago: ImportableVec::forced_import(db, "height_24h_ago", version)?,
|
||||||
|
height_3d_ago: ImportableVec::forced_import(db, "height_3d_ago", version)?,
|
||||||
|
height_1w_ago: ImportableVec::forced_import(db, "height_1w_ago", version)?,
|
||||||
|
height_8d_ago: ImportableVec::forced_import(db, "height_8d_ago", version)?,
|
||||||
|
height_9d_ago: ImportableVec::forced_import(db, "height_9d_ago", version)?,
|
||||||
|
height_12d_ago: ImportableVec::forced_import(db, "height_12d_ago", version)?,
|
||||||
|
height_13d_ago: ImportableVec::forced_import(db, "height_13d_ago", version)?,
|
||||||
|
height_2w_ago: ImportableVec::forced_import(db, "height_2w_ago", version)?,
|
||||||
|
height_21d_ago: ImportableVec::forced_import(db, "height_21d_ago", version)?,
|
||||||
|
height_26d_ago: ImportableVec::forced_import(db, "height_26d_ago", version)?,
|
||||||
|
height_1m_ago: ImportableVec::forced_import(db, "height_1m_ago", version)?,
|
||||||
|
height_34d_ago: ImportableVec::forced_import(db, "height_34d_ago", version)?,
|
||||||
|
height_55d_ago: ImportableVec::forced_import(db, "height_55d_ago", version)?,
|
||||||
|
height_2m_ago: ImportableVec::forced_import(db, "height_2m_ago", version)?,
|
||||||
|
height_9w_ago: ImportableVec::forced_import(db, "height_9w_ago", version)?,
|
||||||
|
height_12w_ago: ImportableVec::forced_import(db, "height_12w_ago", version)?,
|
||||||
|
height_89d_ago: ImportableVec::forced_import(db, "height_89d_ago", version)?,
|
||||||
|
height_3m_ago: ImportableVec::forced_import(db, "height_3m_ago", version)?,
|
||||||
|
height_14w_ago: ImportableVec::forced_import(db, "height_14w_ago", version)?,
|
||||||
|
height_111d_ago: ImportableVec::forced_import(db, "height_111d_ago", version)?,
|
||||||
|
height_144d_ago: ImportableVec::forced_import(db, "height_144d_ago", version)?,
|
||||||
|
height_6m_ago: ImportableVec::forced_import(db, "height_6m_ago", version)?,
|
||||||
|
height_26w_ago: ImportableVec::forced_import(db, "height_26w_ago", version)?,
|
||||||
|
height_200d_ago: ImportableVec::forced_import(db, "height_200d_ago", version)?,
|
||||||
|
height_9m_ago: ImportableVec::forced_import(db, "height_9m_ago", version)?,
|
||||||
|
height_350d_ago: ImportableVec::forced_import(db, "height_350d_ago", version)?,
|
||||||
|
height_12m_ago: ImportableVec::forced_import(db, "height_12m_ago", version)?,
|
||||||
|
height_1y_ago: ImportableVec::forced_import(db, "height_1y_ago", version)?,
|
||||||
|
height_14m_ago: ImportableVec::forced_import(db, "height_14m_ago", version)?,
|
||||||
|
height_2y_ago: ImportableVec::forced_import(db, "height_2y_ago", version)?,
|
||||||
|
height_26m_ago: ImportableVec::forced_import(db, "height_26m_ago", version)?,
|
||||||
|
height_3y_ago: ImportableVec::forced_import(db, "height_3y_ago", version)?,
|
||||||
|
height_200w_ago: ImportableVec::forced_import(db, "height_200w_ago", version)?,
|
||||||
|
height_4y_ago: ImportableVec::forced_import(db, "height_4y_ago", version)?,
|
||||||
|
height_5y_ago: ImportableVec::forced_import(db, "height_5y_ago", version)?,
|
||||||
|
height_6y_ago: ImportableVec::forced_import(db, "height_6y_ago", version)?,
|
||||||
|
height_8y_ago: ImportableVec::forced_import(db, "height_8y_ago", version)?,
|
||||||
|
height_9y_ago: ImportableVec::forced_import(db, "height_9y_ago", version)?,
|
||||||
|
height_10y_ago: ImportableVec::forced_import(db, "height_10y_ago", version)?,
|
||||||
|
height_12y_ago: ImportableVec::forced_import(db, "height_12y_ago", version)?,
|
||||||
|
height_14y_ago: ImportableVec::forced_import(db, "height_14y_ago", version)?,
|
||||||
|
height_26y_ago: ImportableVec::forced_import(db, "height_26y_ago", version)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn window_starts(&self) -> WindowStarts<'_> {
|
||||||
|
WindowStarts {
|
||||||
|
_24h: &self.height_24h_ago,
|
||||||
|
_1w: &self.height_1w_ago,
|
||||||
|
_1m: &self.height_1m_ago,
|
||||||
|
_1y: &self.height_1y_ago,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start_vec(&self, days: usize) -> &EagerVec<PcoVec<Height, Height>> {
|
||||||
|
match days {
|
||||||
|
1 => &self.height_24h_ago,
|
||||||
|
3 => &self.height_3d_ago,
|
||||||
|
7 => &self.height_1w_ago,
|
||||||
|
8 => &self.height_8d_ago,
|
||||||
|
9 => &self.height_9d_ago,
|
||||||
|
12 => &self.height_12d_ago,
|
||||||
|
13 => &self.height_13d_ago,
|
||||||
|
14 => &self.height_2w_ago,
|
||||||
|
21 => &self.height_21d_ago,
|
||||||
|
26 => &self.height_26d_ago,
|
||||||
|
30 => &self.height_1m_ago,
|
||||||
|
34 => &self.height_34d_ago,
|
||||||
|
55 => &self.height_55d_ago,
|
||||||
|
60 => &self.height_2m_ago,
|
||||||
|
63 => &self.height_9w_ago,
|
||||||
|
84 => &self.height_12w_ago,
|
||||||
|
89 => &self.height_89d_ago,
|
||||||
|
90 => &self.height_3m_ago,
|
||||||
|
98 => &self.height_14w_ago,
|
||||||
|
111 => &self.height_111d_ago,
|
||||||
|
144 => &self.height_144d_ago,
|
||||||
|
180 => &self.height_6m_ago,
|
||||||
|
182 => &self.height_26w_ago,
|
||||||
|
200 => &self.height_200d_ago,
|
||||||
|
270 => &self.height_9m_ago,
|
||||||
|
350 => &self.height_350d_ago,
|
||||||
|
360 => &self.height_12m_ago,
|
||||||
|
365 => &self.height_1y_ago,
|
||||||
|
420 => &self.height_14m_ago,
|
||||||
|
730 => &self.height_2y_ago,
|
||||||
|
780 => &self.height_26m_ago,
|
||||||
|
1095 => &self.height_3y_ago,
|
||||||
|
1400 => &self.height_200w_ago,
|
||||||
|
1460 => &self.height_4y_ago,
|
||||||
|
1825 => &self.height_5y_ago,
|
||||||
|
2190 => &self.height_6y_ago,
|
||||||
|
2920 => &self.height_8y_ago,
|
||||||
|
3285 => &self.height_9y_ago,
|
||||||
|
3650 => &self.height_10y_ago,
|
||||||
|
4380 => &self.height_12y_ago,
|
||||||
|
5110 => &self.height_14y_ago,
|
||||||
|
9490 => &self.height_26y_ago,
|
||||||
|
_ => panic!("No start vec for {days} days"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute(
|
||||||
|
&mut self,
|
||||||
|
time: &time::Vecs,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.compute_rolling_start_hours(time, starting_indexes, exit, 1, |s| {
|
||||||
|
&mut s.height_1h_ago
|
||||||
|
})?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 1, |s| &mut s.height_24h_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 3, |s| &mut s.height_3d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 7, |s| &mut s.height_1w_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 8, |s| &mut s.height_8d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 9, |s| &mut s.height_9d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 12, |s| &mut s.height_12d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 13, |s| &mut s.height_13d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 14, |s| &mut s.height_2w_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 21, |s| &mut s.height_21d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 26, |s| &mut s.height_26d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 30, |s| &mut s.height_1m_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 34, |s| &mut s.height_34d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 55, |s| &mut s.height_55d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 60, |s| &mut s.height_2m_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 63, |s| &mut s.height_9w_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 84, |s| &mut s.height_12w_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 89, |s| &mut s.height_89d_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 90, |s| &mut s.height_3m_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 98, |s| &mut s.height_14w_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 111, |s| {
|
||||||
|
&mut s.height_111d_ago
|
||||||
|
})?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 144, |s| {
|
||||||
|
&mut s.height_144d_ago
|
||||||
|
})?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 180, |s| &mut s.height_6m_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 182, |s| &mut s.height_26w_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 200, |s| {
|
||||||
|
&mut s.height_200d_ago
|
||||||
|
})?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 270, |s| &mut s.height_9m_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 350, |s| {
|
||||||
|
&mut s.height_350d_ago
|
||||||
|
})?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 360, |s| &mut s.height_12m_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 365, |s| &mut s.height_1y_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 420, |s| &mut s.height_14m_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 730, |s| &mut s.height_2y_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 780, |s| &mut s.height_26m_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 1095, |s| &mut s.height_3y_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 1400, |s| {
|
||||||
|
&mut s.height_200w_ago
|
||||||
|
})?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 1460, |s| &mut s.height_4y_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 1825, |s| &mut s.height_5y_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 2190, |s| &mut s.height_6y_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 2920, |s| &mut s.height_8y_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 3285, |s| &mut s.height_9y_ago)?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 3650, |s| {
|
||||||
|
&mut s.height_10y_ago
|
||||||
|
})?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 4380, |s| {
|
||||||
|
&mut s.height_12y_ago
|
||||||
|
})?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 5110, |s| {
|
||||||
|
&mut s.height_14y_ago
|
||||||
|
})?;
|
||||||
|
self.compute_rolling_start(time, starting_indexes, exit, 9490, |s| {
|
||||||
|
&mut s.height_26y_ago
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_rolling_start<F>(
|
||||||
|
&mut self,
|
||||||
|
time: &time::Vecs,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
exit: &Exit,
|
||||||
|
days: usize,
|
||||||
|
get_field: F,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
|
||||||
|
{
|
||||||
|
self.compute_rolling_start_inner(time, starting_indexes, exit, get_field, |t, prev_ts| {
|
||||||
|
t.difference_in_days_between(prev_ts) >= days
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_rolling_start_hours<F>(
|
||||||
|
&mut self,
|
||||||
|
time: &time::Vecs,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
exit: &Exit,
|
||||||
|
hours: usize,
|
||||||
|
get_field: F,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
|
||||||
|
{
|
||||||
|
self.compute_rolling_start_inner(time, starting_indexes, exit, get_field, |t, prev_ts| {
|
||||||
|
t.difference_in_hours_between(prev_ts) >= hours
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_rolling_start_inner<F, D>(
|
||||||
|
&mut self,
|
||||||
|
time: &time::Vecs,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
exit: &Exit,
|
||||||
|
get_field: F,
|
||||||
|
expired: D,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
|
||||||
|
D: Fn(Timestamp, Timestamp) -> bool,
|
||||||
|
{
|
||||||
|
let field = get_field(self);
|
||||||
|
let resume_from = field.len().min(starting_indexes.height.to_usize());
|
||||||
|
let mut prev = if resume_from > 0 {
|
||||||
|
field.collect_one_at(resume_from - 1).unwrap()
|
||||||
|
} else {
|
||||||
|
Height::ZERO
|
||||||
|
};
|
||||||
|
let mut cursor = Cursor::new(&time.timestamp_monotonic);
|
||||||
|
cursor.advance(prev.to_usize());
|
||||||
|
let mut prev_ts = cursor.next().unwrap();
|
||||||
|
Ok(field.compute_transform(
|
||||||
|
starting_indexes.height,
|
||||||
|
&time.timestamp_monotonic,
|
||||||
|
|(h, t, ..)| {
|
||||||
|
while expired(t, prev_ts) {
|
||||||
|
prev.increment();
|
||||||
|
prev_ts = cursor.next().unwrap();
|
||||||
|
if prev > h {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(h, prev)
|
||||||
|
},
|
||||||
|
exit,
|
||||||
|
)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ pub mod count;
|
|||||||
pub mod difficulty;
|
pub mod difficulty;
|
||||||
pub mod halving;
|
pub mod halving;
|
||||||
pub mod interval;
|
pub mod interval;
|
||||||
|
pub mod lookback;
|
||||||
pub mod size;
|
pub mod size;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
pub mod weight;
|
pub mod weight;
|
||||||
@@ -16,6 +17,7 @@ pub use count::Vecs as CountVecs;
|
|||||||
pub use difficulty::Vecs as DifficultyVecs;
|
pub use difficulty::Vecs as DifficultyVecs;
|
||||||
pub use halving::Vecs as HalvingVecs;
|
pub use halving::Vecs as HalvingVecs;
|
||||||
pub use interval::Vecs as IntervalVecs;
|
pub use interval::Vecs as IntervalVecs;
|
||||||
|
pub use lookback::Vecs as LookbackVecs;
|
||||||
pub use size::Vecs as SizeVecs;
|
pub use size::Vecs as SizeVecs;
|
||||||
pub use time::Vecs as TimeVecs;
|
pub use time::Vecs as TimeVecs;
|
||||||
pub use weight::Vecs as WeightVecs;
|
pub use weight::Vecs as WeightVecs;
|
||||||
@@ -46,6 +48,7 @@ pub struct Vecs<M: StorageMode = Rw> {
|
|||||||
pub(crate) db: Database,
|
pub(crate) db: Database,
|
||||||
|
|
||||||
pub count: CountVecs<M>,
|
pub count: CountVecs<M>,
|
||||||
|
pub lookback: LookbackVecs<M>,
|
||||||
pub interval: IntervalVecs<M>,
|
pub interval: IntervalVecs<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub size: SizeVecs<M>,
|
pub size: SizeVecs<M>,
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ impl Vecs {
|
|||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
indexer: &Indexer,
|
indexer: &Indexer,
|
||||||
count_vecs: &blocks::CountVecs,
|
lookback: &blocks::LookbackVecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = lookback.window_starts();
|
||||||
|
|
||||||
// vbytes = floor(weight / 4), stored at height level
|
// vbytes = floor(weight / 4), stored at height level
|
||||||
self.vbytes
|
self.vbytes
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ impl Vecs {
|
|||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
indexer: &Indexer,
|
indexer: &Indexer,
|
||||||
count_vecs: &blocks::CountVecs,
|
lookback: &blocks::LookbackVecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = lookback.window_starts();
|
||||||
|
|
||||||
self.weight.compute(
|
self.weight.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ impl Vecs {
|
|||||||
distribution: &distribution::Vecs,
|
distribution: &distribution::Vecs,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
|
|
||||||
let all_metrics = &distribution.utxo_cohorts.all.metrics;
|
let all_metrics = &distribution.utxo_cohorts.all.metrics;
|
||||||
let circulating_supply = &all_metrics.supply.total.sats.height;
|
let circulating_supply = &all_metrics.supply.total.sats.height;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ impl Vecs {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.vocdd_median_1y.compute_rolling_median_from_starts(
|
self.vocdd_median_1y.compute_rolling_median_from_starts(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1y_ago,
|
&blocks.lookback.height_1y_ago,
|
||||||
&value.vocdd.height,
|
&value.vocdd.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use brk_types::Version;
|
|||||||
use vecdb::Database;
|
use vecdb::Database;
|
||||||
|
|
||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{indexes, internal::ValueFromHeight};
|
use crate::{indexes, internal::AmountFromHeight};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
@@ -12,8 +12,13 @@ impl Vecs {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
vaulted_supply: ValueFromHeight::forced_import(db, "vaulted_supply", version, indexes)?,
|
vaulted_supply: AmountFromHeight::forced_import(
|
||||||
active_supply: ValueFromHeight::forced_import(db, "active_supply", version, indexes)?,
|
db,
|
||||||
|
"vaulted_supply",
|
||||||
|
version,
|
||||||
|
indexes,
|
||||||
|
)?,
|
||||||
|
active_supply: AmountFromHeight::forced_import(db, "active_supply", version, indexes)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use vecdb::{Rw, StorageMode};
|
use vecdb::{Rw, StorageMode};
|
||||||
|
|
||||||
use crate::internal::ValueFromHeight;
|
use crate::internal::AmountFromHeight;
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
pub vaulted_supply: ValueFromHeight<M>,
|
pub vaulted_supply: AmountFromHeight<M>,
|
||||||
pub active_supply: ValueFromHeight<M>,
|
pub active_supply: AmountFromHeight<M>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ impl Vecs {
|
|||||||
activity: &activity::Vecs,
|
activity: &activity::Vecs,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
|
|
||||||
let all_metrics = &distribution.utxo_cohorts.all.metrics;
|
let all_metrics = &distribution.utxo_cohorts.all.metrics;
|
||||||
let coinblocks_destroyed = &all_metrics.activity.coinblocks_destroyed;
|
let coinblocks_destroyed = &all_metrics.activity.coinblocks_destroyed;
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ impl AddressCohorts {
|
|||||||
self.par_iter_mut().try_for_each(|v| {
|
self.par_iter_mut().try_for_each(|v| {
|
||||||
v.addr_count_delta.compute(
|
v.addr_count_delta.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1m_ago,
|
&blocks.lookback.height_1m_ago,
|
||||||
&v.addr_count.height,
|
&v.addr_count.height,
|
||||||
exit,
|
exit,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ use brk_error::Result;
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Dollars, Height, Indexes, Sats, Version};
|
use brk_types::{Dollars, Height, Indexes, Sats, Version};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use vecdb::{AnyStoredVec, Database, Exit, ReadOnlyClone, ReadableVec, Rw, StorageMode, WritableVec};
|
use vecdb::{
|
||||||
|
AnyStoredVec, Database, Exit, ReadOnlyClone, ReadableVec, Rw, StorageMode, WritableVec,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blocks,
|
blocks,
|
||||||
@@ -22,7 +24,7 @@ use crate::{
|
|||||||
state::UTXOCohortState,
|
state::UTXOCohortState,
|
||||||
},
|
},
|
||||||
indexes,
|
indexes,
|
||||||
internal::ValueFromHeight,
|
internal::AmountFromHeight,
|
||||||
prices,
|
prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,7 +49,7 @@ pub struct UTXOCohorts<M: StorageMode = Rw> {
|
|||||||
#[traversable(rename = "type")]
|
#[traversable(rename = "type")]
|
||||||
pub type_: BySpendableType<UTXOCohortVecs<MinimalCohortMetrics<M>>>,
|
pub type_: BySpendableType<UTXOCohortVecs<MinimalCohortMetrics<M>>>,
|
||||||
pub profitability: ProfitabilityMetrics<M>,
|
pub profitability: ProfitabilityMetrics<M>,
|
||||||
pub matured: ByAgeRange<ValueFromHeight<M>>,
|
pub matured: ByAgeRange<AmountFromHeight<M>>,
|
||||||
#[traversable(skip)]
|
#[traversable(skip)]
|
||||||
pub(super) fenwick: CostBasisFenwick,
|
pub(super) fenwick: CostBasisFenwick,
|
||||||
/// Cached partition_point positions for tick_tock boundary searches.
|
/// Cached partition_point positions for tick_tock boundary searches.
|
||||||
@@ -226,8 +228,10 @@ impl UTXOCohorts<Rw> {
|
|||||||
let lt_amount = ByLowerThanAmount::try_new(&minimal_no_state)?;
|
let lt_amount = ByLowerThanAmount::try_new(&minimal_no_state)?;
|
||||||
let ge_amount = ByGreatEqualAmount::try_new(&minimal_no_state)?;
|
let ge_amount = ByGreatEqualAmount::try_new(&minimal_no_state)?;
|
||||||
|
|
||||||
let matured = ByAgeRange::try_new(&|_f: Filter, name: &'static str| -> Result<ValueFromHeight> {
|
let matured = ByAgeRange::try_new(&|_f: Filter,
|
||||||
ValueFromHeight::forced_import(db, &format!("utxo_{name}_matured"), v, indexes)
|
name: &'static str|
|
||||||
|
-> Result<AmountFromHeight> {
|
||||||
|
AmountFromHeight::forced_import(db, &format!("utxo_{name}_matured"), v, indexes)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -257,7 +261,10 @@ impl UTXOCohorts<Rw> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Self {
|
let Self {
|
||||||
sth, fenwick, age_range, ..
|
sth,
|
||||||
|
fenwick,
|
||||||
|
age_range,
|
||||||
|
..
|
||||||
} = self;
|
} = self;
|
||||||
fenwick.compute_is_sth(&sth.metrics.filter, age_range.iter().map(|v| v.filter()));
|
fenwick.compute_is_sth(&sth.metrics.filter, age_range.iter().map(|v| v.filter()));
|
||||||
|
|
||||||
@@ -334,9 +341,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
|
|
||||||
/// Sequential mutable iterator over all separate (stateful) cohorts.
|
/// Sequential mutable iterator over all separate (stateful) cohorts.
|
||||||
/// Use instead of `par_iter_separate_mut` when per-item work is trivial.
|
/// Use instead of `par_iter_separate_mut` when per-item work is trivial.
|
||||||
pub(crate) fn iter_separate_mut(
|
pub(crate) fn iter_separate_mut(&mut self) -> impl Iterator<Item = &mut dyn DynCohortVecs> {
|
||||||
&mut self,
|
|
||||||
) -> impl Iterator<Item = &mut dyn DynCohortVecs> {
|
|
||||||
let Self {
|
let Self {
|
||||||
age_range,
|
age_range,
|
||||||
epoch,
|
epoch,
|
||||||
@@ -575,35 +580,20 @@ impl UTXOCohorts<Rw> {
|
|||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
age_range.par_iter_mut().try_for_each(|v| {
|
age_range.par_iter_mut().try_for_each(|v| {
|
||||||
v.metrics.compute_rest_part2(
|
v.metrics
|
||||||
blocks,
|
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
|
||||||
prices,
|
|
||||||
starting_indexes,
|
|
||||||
ss,
|
|
||||||
exit,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
max_age.par_iter_mut().try_for_each(|v| {
|
max_age.par_iter_mut().try_for_each(|v| {
|
||||||
v.metrics.compute_rest_part2(
|
v.metrics
|
||||||
blocks,
|
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
|
||||||
prices,
|
|
||||||
starting_indexes,
|
|
||||||
ss,
|
|
||||||
exit,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
min_age.par_iter_mut().try_for_each(|v| {
|
min_age.par_iter_mut().try_for_each(|v| {
|
||||||
v.metrics.compute_rest_part2(
|
v.metrics
|
||||||
blocks,
|
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
|
||||||
prices,
|
|
||||||
starting_indexes,
|
|
||||||
ss,
|
|
||||||
exit,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
@@ -613,24 +603,14 @@ impl UTXOCohorts<Rw> {
|
|||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
epoch.par_iter_mut().try_for_each(|v| {
|
epoch.par_iter_mut().try_for_each(|v| {
|
||||||
v.metrics.compute_rest_part2(
|
v.metrics
|
||||||
blocks,
|
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
|
||||||
prices,
|
|
||||||
starting_indexes,
|
|
||||||
ss,
|
|
||||||
exit,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
class.par_iter_mut().try_for_each(|v| {
|
class.par_iter_mut().try_for_each(|v| {
|
||||||
v.metrics.compute_rest_part2(
|
v.metrics
|
||||||
blocks,
|
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
|
||||||
prices,
|
|
||||||
starting_indexes,
|
|
||||||
ss,
|
|
||||||
exit,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
@@ -695,9 +675,8 @@ impl UTXOCohorts<Rw> {
|
|||||||
}
|
}
|
||||||
vecs.extend(self.profitability.collect_all_vecs_mut());
|
vecs.extend(self.profitability.collect_all_vecs_mut());
|
||||||
for v in self.matured.iter_mut() {
|
for v in self.matured.iter_mut() {
|
||||||
let base = &mut v.base;
|
vecs.push(&mut v.sats.height);
|
||||||
vecs.push(&mut base.sats.height);
|
vecs.push(&mut v.cents.height);
|
||||||
vecs.push(&mut base.cents.height);
|
|
||||||
}
|
}
|
||||||
vecs.into_par_iter()
|
vecs.into_par_iter()
|
||||||
}
|
}
|
||||||
@@ -712,13 +691,23 @@ impl UTXOCohorts<Rw> {
|
|||||||
pub(crate) fn min_separate_stateful_height_len(&self) -> Height {
|
pub(crate) fn min_separate_stateful_height_len(&self) -> Height {
|
||||||
self.iter_separate()
|
self.iter_separate()
|
||||||
.map(|v| Height::from(v.min_stateful_height_len()))
|
.map(|v| Height::from(v.min_stateful_height_len()))
|
||||||
.chain(self.matured.iter().map(|v| Height::from(v.min_stateful_len())))
|
.chain(
|
||||||
|
self.matured
|
||||||
|
.iter()
|
||||||
|
.map(|v| Height::from(v.min_stateful_len())),
|
||||||
|
)
|
||||||
.min()
|
.min()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.min(Height::from(self.profitability.min_stateful_height_len()))
|
.min(Height::from(self.profitability.min_stateful_height_len()))
|
||||||
.min(Height::from(self.all.metrics.realized.min_stateful_height_len()))
|
.min(Height::from(
|
||||||
.min(Height::from(self.sth.metrics.realized.min_stateful_height_len()))
|
self.all.metrics.realized.min_stateful_height_len(),
|
||||||
.min(Height::from(self.lth.metrics.realized.min_stateful_height_len()))
|
))
|
||||||
|
.min(Height::from(
|
||||||
|
self.sth.metrics.realized.min_stateful_height_len(),
|
||||||
|
))
|
||||||
|
.min(Height::from(
|
||||||
|
self.lth.metrics.realized.min_stateful_height_len(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Import state for all separate cohorts at or before given height.
|
/// Import state for all separate cohorts at or before given height.
|
||||||
@@ -770,7 +759,11 @@ impl UTXOCohorts<Rw> {
|
|||||||
/// Called during the block loop after separate cohorts' truncate_push but before reset.
|
/// Called during the block loop after separate cohorts' truncate_push but before reset.
|
||||||
pub(crate) fn push_overlapping_realized_full(&mut self, height: Height) -> Result<()> {
|
pub(crate) fn push_overlapping_realized_full(&mut self, height: Height) -> Result<()> {
|
||||||
let Self {
|
let Self {
|
||||||
all, sth, lth, age_range, ..
|
all,
|
||||||
|
sth,
|
||||||
|
lth,
|
||||||
|
age_range,
|
||||||
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let sth_filter = &sth.metrics.filter;
|
let sth_filter = &sth.metrics.filter;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ impl ActivityCore {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.sent_sum.compute_rolling_sum(
|
self.sent_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_24h_ago,
|
&blocks.lookback.height_24h_ago,
|
||||||
&self.sent.height,
|
&self.sent.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ pub struct ActivityFull<M: StorageMode = Rw> {
|
|||||||
pub coindays_destroyed_cumulative: ComputedFromHeight<StoredF64, M>,
|
pub coindays_destroyed_cumulative: ComputedFromHeight<StoredF64, M>,
|
||||||
pub coindays_destroyed_sum: RollingWindows<StoredF64, M>,
|
pub coindays_destroyed_sum: RollingWindows<StoredF64, M>,
|
||||||
|
|
||||||
|
#[traversable(rename = "sent_sum")]
|
||||||
pub sent_sum_extended: RollingWindowsFrom1w<Sats, M>,
|
pub sent_sum_extended: RollingWindowsFrom1w<Sats, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +73,7 @@ impl ActivityFull {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
self.coindays_destroyed_sum.compute_rolling_sum(
|
self.coindays_destroyed_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&window_starts,
|
&window_starts,
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ pub struct AllCohortMetrics<M: StorageMode = Rw> {
|
|||||||
pub dormancy: ComputedFromHeight<StoredF32, M>,
|
pub dormancy: ComputedFromHeight<StoredF32, M>,
|
||||||
pub velocity: ComputedFromHeight<StoredF32, M>,
|
pub velocity: ComputedFromHeight<StoredF32, M>,
|
||||||
|
|
||||||
|
#[traversable(wrap = "supply", rename = "delta")]
|
||||||
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
|
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
|
||||||
|
#[traversable(wrap = "outputs", rename = "utxo_count_delta")]
|
||||||
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
|
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +149,7 @@ impl AllCohortMetrics {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
self.supply_delta_extended.compute(
|
self.supply_delta_extended.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&window_starts,
|
&window_starts,
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ pub struct ExtendedCohortMetrics<M: StorageMode = Rw> {
|
|||||||
pub dormancy: ComputedFromHeight<StoredF32, M>,
|
pub dormancy: ComputedFromHeight<StoredF32, M>,
|
||||||
pub velocity: ComputedFromHeight<StoredF32, M>,
|
pub velocity: ComputedFromHeight<StoredF32, M>,
|
||||||
|
|
||||||
|
#[traversable(wrap = "supply", rename = "delta")]
|
||||||
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
|
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
|
||||||
|
#[traversable(wrap = "outputs", rename = "utxo_count_delta")]
|
||||||
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
|
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +128,7 @@ impl ExtendedCohortMetrics {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
self.supply_delta_extended.compute(
|
self.supply_delta_extended.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&window_starts,
|
&window_starts,
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
use brk_cohort::Filter;
|
use brk_cohort::Filter;
|
||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_types::{
|
use brk_types::{BasisPoints16, BasisPoints32, BasisPointsSigned32, Cents, Height, Version};
|
||||||
BasisPoints16, BasisPoints32, BasisPointsSigned32, Cents, Height, Version,
|
|
||||||
};
|
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use vecdb::{BytesVec, BytesVecValue, Database, ImportableVec};
|
use vecdb::{BytesVec, BytesVecValue, Database, ImportableVec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{
|
internal::{
|
||||||
CentsType, ComputedFromHeight, ComputedFromHeightCumulative,
|
AmountFromHeight, AmountFromHeightCumulative, CentsType, ComputedFromHeight,
|
||||||
ComputedFromHeightCumulativeSum, ComputedFromHeightRatio, FiatFromHeight,
|
ComputedFromHeightCumulative, ComputedFromHeightCumulativeSum, ComputedFromHeightRatio,
|
||||||
FiatRollingDelta1m, FiatRollingDeltaExcept1m, NumericValue, PercentFromHeight,
|
FiatFromHeight, FiatRollingDelta1m, FiatRollingDeltaExcept1m, NumericValue,
|
||||||
PercentRollingWindows, Price, RollingDelta1m, RollingDeltaExcept1m, RollingWindow24h,
|
PercentFromHeight, PercentRollingWindows, Price, RollingDelta1m, RollingDeltaExcept1m,
|
||||||
RollingWindows, RollingWindowsFrom1w, ValueFromHeight, ValueFromHeightCumulative,
|
RollingWindow24h, RollingWindows, RollingWindowsFrom1w,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,8 +35,8 @@ macro_rules! impl_config_import {
|
|||||||
|
|
||||||
// Non-generic types
|
// Non-generic types
|
||||||
impl_config_import!(
|
impl_config_import!(
|
||||||
ValueFromHeight,
|
AmountFromHeight,
|
||||||
ValueFromHeightCumulative,
|
AmountFromHeightCumulative,
|
||||||
ComputedFromHeightRatio,
|
ComputedFromHeightRatio,
|
||||||
PercentFromHeight<BasisPoints16>,
|
PercentFromHeight<BasisPoints16>,
|
||||||
PercentFromHeight<BasisPoints32>,
|
PercentFromHeight<BasisPoints32>,
|
||||||
@@ -83,7 +81,8 @@ impl<C: CentsType> ConfigImport for FiatFromHeight<C> {
|
|||||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<S: NumericValue + JsonSchema, C: NumericValue + JsonSchema> ConfigImport for RollingDelta1m<S, C>
|
impl<S: NumericValue + JsonSchema, C: NumericValue + JsonSchema> ConfigImport
|
||||||
|
for RollingDelta1m<S, C>
|
||||||
{
|
{
|
||||||
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
||||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||||
@@ -136,11 +135,7 @@ impl<'a> ImportConfig<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn import<T: ConfigImport>(
|
pub(crate) fn import<T: ConfigImport>(&self, suffix: &str, offset: Version) -> Result<T> {
|
||||||
&self,
|
|
||||||
suffix: &str,
|
|
||||||
offset: Version,
|
|
||||||
) -> Result<T> {
|
|
||||||
T::config_import(self, suffix, offset)
|
T::config_import(self, suffix, offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ impl OutputsMetrics {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.utxo_count_delta.compute(
|
self.utxo_count_delta.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1m_ago,
|
&blocks.lookback.height_1m_ago,
|
||||||
&self.utxo_count.height,
|
&self.utxo_count.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -12,23 +12,21 @@ use crate::distribution::metrics::ImportConfig;
|
|||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct RealizedAdjusted<M: StorageMode = Rw> {
|
pub struct RealizedAdjusted<M: StorageMode = Rw> {
|
||||||
pub adjusted_value_created: ComputedFromHeight<Cents, M>,
|
pub value_created: ComputedFromHeight<Cents, M>,
|
||||||
pub adjusted_value_destroyed: ComputedFromHeight<Cents, M>,
|
pub value_destroyed: ComputedFromHeight<Cents, M>,
|
||||||
|
pub value_created_sum: RollingWindows<Cents, M>,
|
||||||
pub adjusted_value_created_sum: RollingWindows<Cents, M>,
|
pub value_destroyed_sum: RollingWindows<Cents, M>,
|
||||||
pub adjusted_value_destroyed_sum: RollingWindows<Cents, M>,
|
pub sopr: RollingWindows<StoredF64, M>,
|
||||||
|
|
||||||
pub adjusted_sopr: RollingWindows<StoredF64, M>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RealizedAdjusted {
|
impl RealizedAdjusted {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
Ok(RealizedAdjusted {
|
Ok(RealizedAdjusted {
|
||||||
adjusted_value_created: cfg.import("adjusted_value_created", Version::ZERO)?,
|
value_created: cfg.import("adjusted_value_created", Version::ZERO)?,
|
||||||
adjusted_value_destroyed: cfg.import("adjusted_value_destroyed", Version::ZERO)?,
|
value_destroyed: cfg.import("adjusted_value_destroyed", Version::ZERO)?,
|
||||||
adjusted_value_created_sum: cfg.import("adjusted_value_created", Version::ONE)?,
|
value_created_sum: cfg.import("adjusted_value_created", Version::ONE)?,
|
||||||
adjusted_value_destroyed_sum: cfg.import("adjusted_value_destroyed", Version::ONE)?,
|
value_destroyed_sum: cfg.import("adjusted_value_destroyed", Version::ONE)?,
|
||||||
adjusted_sopr: cfg.import("adjusted_sopr", Version::ONE)?,
|
sopr: cfg.import("adjusted_sopr", Version::ONE)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,14 +41,14 @@ impl RealizedAdjusted {
|
|||||||
up_to_1h_value_destroyed: &impl ReadableVec<Height, Cents>,
|
up_to_1h_value_destroyed: &impl ReadableVec<Height, Cents>,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Compute adjusted_value_created = base.value_created - up_to_1h.value_created
|
// Compute value_created = base.value_created - up_to_1h.value_created
|
||||||
self.adjusted_value_created.height.compute_subtract(
|
self.value_created.height.compute_subtract(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
base_value_created,
|
base_value_created,
|
||||||
up_to_1h_value_created,
|
up_to_1h_value_created,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.adjusted_value_destroyed.height.compute_subtract(
|
self.value_destroyed.height.compute_subtract(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
base_value_destroyed,
|
base_value_destroyed,
|
||||||
up_to_1h_value_destroyed,
|
up_to_1h_value_destroyed,
|
||||||
@@ -58,27 +56,27 @@ impl RealizedAdjusted {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Adjusted value created/destroyed rolling sums
|
// Adjusted value created/destroyed rolling sums
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
self.adjusted_value_created_sum.compute_rolling_sum(
|
self.value_created_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&window_starts,
|
&window_starts,
|
||||||
&self.adjusted_value_created.height,
|
&self.value_created.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.adjusted_value_destroyed_sum.compute_rolling_sum(
|
self.value_destroyed_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&window_starts,
|
&window_starts,
|
||||||
&self.adjusted_value_destroyed.height,
|
&self.value_destroyed.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// SOPR ratios from rolling sums
|
// SOPR ratios from rolling sums
|
||||||
for ((sopr, vc), vd) in self
|
for ((sopr, vc), vd) in self
|
||||||
.adjusted_sopr
|
.sopr
|
||||||
.as_mut_array()
|
.as_mut_array()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(self.adjusted_value_created_sum.as_array())
|
.zip(self.value_created_sum.as_array())
|
||||||
.zip(self.adjusted_value_destroyed_sum.as_array())
|
.zip(self.value_destroyed_sum.as_array())
|
||||||
{
|
{
|
||||||
sopr.compute_binary::<Cents, Cents, RatioCents64>(
|
sopr.compute_binary::<Cents, Cents, RatioCents64>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
|
|||||||
@@ -91,13 +91,13 @@ impl RealizedBase {
|
|||||||
self.core.compute_rest_part1(blocks, starting_indexes, exit)?;
|
self.core.compute_rest_part1(blocks, starting_indexes, exit)?;
|
||||||
self.sent_in_profit_sum.compute_rolling_sum(
|
self.sent_in_profit_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_24h_ago,
|
&blocks.lookback.height_24h_ago,
|
||||||
&self.sent_in_profit.height,
|
&self.sent_in_profit.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.sent_in_loss_sum.compute_rolling_sum(
|
self.sent_in_loss_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_24h_ago,
|
&blocks.lookback.height_24h_ago,
|
||||||
&self.sent_in_loss.height,
|
&self.sent_in_loss.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -155,27 +155,27 @@ impl RealizedCore {
|
|||||||
|
|
||||||
self.realized_cap_delta.compute(
|
self.realized_cap_delta.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1m_ago,
|
&blocks.lookback.height_1m_ago,
|
||||||
&self.minimal.realized_cap_cents.height,
|
&self.minimal.realized_cap_cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.net_realized_pnl_sum.compute_rolling_sum(
|
self.net_realized_pnl_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_24h_ago,
|
&blocks.lookback.height_24h_ago,
|
||||||
&self.net_realized_pnl.height,
|
&self.net_realized_pnl.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.value_created_sum.compute_rolling_sum(
|
self.value_created_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_24h_ago,
|
&blocks.lookback.height_24h_ago,
|
||||||
&self.value_created.height,
|
&self.value_created.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.value_destroyed_sum.compute_rolling_sum(
|
self.value_destroyed_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_24h_ago,
|
&blocks.lookback.height_24h_ago,
|
||||||
&self.value_destroyed.height,
|
&self.value_destroyed.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -57,13 +57,16 @@ pub struct RealizedFull<M: StorageMode = Rw> {
|
|||||||
pub gross_pnl_sum: RollingWindows<Cents, M>,
|
pub gross_pnl_sum: RollingWindows<Cents, M>,
|
||||||
|
|
||||||
pub net_realized_pnl_cumulative: ComputedFromHeight<CentsSigned, M>,
|
pub net_realized_pnl_cumulative: ComputedFromHeight<CentsSigned, M>,
|
||||||
|
#[traversable(rename = "net_realized_pnl_sum")]
|
||||||
pub net_realized_pnl_sum_extended: RollingWindowsFrom1w<CentsSigned, M>,
|
pub net_realized_pnl_sum_extended: RollingWindowsFrom1w<CentsSigned, M>,
|
||||||
|
|
||||||
pub net_pnl_delta: FiatRollingDelta1m<CentsSigned, CentsSigned, M>,
|
pub net_pnl_delta: FiatRollingDelta1m<CentsSigned, CentsSigned, M>,
|
||||||
|
#[traversable(rename = "net_pnl_delta")]
|
||||||
pub net_pnl_delta_extended: FiatRollingDeltaExcept1m<CentsSigned, CentsSigned, M>,
|
pub net_pnl_delta_extended: FiatRollingDeltaExcept1m<CentsSigned, CentsSigned, M>,
|
||||||
pub net_pnl_change_1m_rel_to_realized_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
pub net_pnl_change_1m_rel_to_realized_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
||||||
pub net_pnl_change_1m_rel_to_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
pub net_pnl_change_1m_rel_to_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
||||||
|
|
||||||
|
#[traversable(rename = "realized_cap_delta")]
|
||||||
pub realized_cap_delta_extended: FiatRollingDeltaExcept1m<Cents, CentsSigned, M>,
|
pub realized_cap_delta_extended: FiatRollingDeltaExcept1m<Cents, CentsSigned, M>,
|
||||||
|
|
||||||
pub investor_price: Price<ComputedFromHeight<Cents, M>>,
|
pub investor_price: Price<ComputedFromHeight<Cents, M>>,
|
||||||
@@ -82,15 +85,22 @@ pub struct RealizedFull<M: StorageMode = Rw> {
|
|||||||
|
|
||||||
pub realized_cap_rel_to_own_market_cap: PercentFromHeight<BasisPoints32, M>,
|
pub realized_cap_rel_to_own_market_cap: PercentFromHeight<BasisPoints32, M>,
|
||||||
|
|
||||||
|
#[traversable(rename = "realized_profit_sum")]
|
||||||
pub realized_profit_sum_extended: RollingWindowsFrom1w<Cents, M>,
|
pub realized_profit_sum_extended: RollingWindowsFrom1w<Cents, M>,
|
||||||
|
#[traversable(rename = "realized_loss_sum")]
|
||||||
pub realized_loss_sum_extended: RollingWindowsFrom1w<Cents, M>,
|
pub realized_loss_sum_extended: RollingWindowsFrom1w<Cents, M>,
|
||||||
pub realized_profit_to_loss_ratio: RollingWindows<StoredF64, M>,
|
pub realized_profit_to_loss_ratio: RollingWindows<StoredF64, M>,
|
||||||
|
|
||||||
|
#[traversable(rename = "value_created_sum")]
|
||||||
pub value_created_sum_extended: RollingWindowsFrom1w<Cents, M>,
|
pub value_created_sum_extended: RollingWindowsFrom1w<Cents, M>,
|
||||||
|
#[traversable(rename = "value_destroyed_sum")]
|
||||||
pub value_destroyed_sum_extended: RollingWindowsFrom1w<Cents, M>,
|
pub value_destroyed_sum_extended: RollingWindowsFrom1w<Cents, M>,
|
||||||
|
#[traversable(rename = "sopr")]
|
||||||
pub sopr_extended: RollingWindowsFrom1w<StoredF64, M>,
|
pub sopr_extended: RollingWindowsFrom1w<StoredF64, M>,
|
||||||
|
|
||||||
|
#[traversable(rename = "sent_in_profit_sum")]
|
||||||
pub sent_in_profit_sum_extended: RollingWindowsFrom1w<Sats, M>,
|
pub sent_in_profit_sum_extended: RollingWindowsFrom1w<Sats, M>,
|
||||||
|
#[traversable(rename = "sent_in_loss_sum")]
|
||||||
pub sent_in_loss_sum_extended: RollingWindowsFrom1w<Sats, M>,
|
pub sent_in_loss_sum_extended: RollingWindowsFrom1w<Sats, M>,
|
||||||
|
|
||||||
pub realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
|
pub realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
|
||||||
@@ -377,7 +387,7 @@ impl RealizedFull {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
|
|
||||||
// Extended rolling sum (1w, 1m, 1y) for net_realized_pnl
|
// Extended rolling sum (1w, 1m, 1y) for net_realized_pnl
|
||||||
self.net_realized_pnl_sum_extended.compute_rolling_sum(
|
self.net_realized_pnl_sum_extended.compute_rolling_sum(
|
||||||
@@ -496,7 +506,7 @@ impl RealizedFull {
|
|||||||
// Net PnL delta (1m base + 24h/1w/1y extended)
|
// Net PnL delta (1m base + 24h/1w/1y extended)
|
||||||
self.net_pnl_delta.compute(
|
self.net_pnl_delta.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1m_ago,
|
&blocks.lookback.height_1m_ago,
|
||||||
&self.net_realized_pnl_cumulative.height,
|
&self.net_realized_pnl_cumulative.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -127,13 +127,13 @@ impl RealizedMinimal {
|
|||||||
.compute_rest(starting_indexes.height, exit)?;
|
.compute_rest(starting_indexes.height, exit)?;
|
||||||
self.realized_profit_sum.compute_rolling_sum(
|
self.realized_profit_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_24h_ago,
|
&blocks.lookback.height_24h_ago,
|
||||||
&self.realized_profit.height,
|
&self.realized_profit.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.realized_loss_sum.compute_rolling_sum(
|
self.realized_loss_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_24h_ago,
|
&blocks.lookback.height_24h_ago,
|
||||||
&self.realized_loss.height,
|
&self.realized_loss.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use crate::{blocks, prices};
|
|||||||
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
||||||
|
|
||||||
use crate::internal::{
|
use crate::internal::{
|
||||||
HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyValueFromHeight,
|
AmountFromHeight, HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin,
|
||||||
RollingDelta1m, ValueFromHeight,
|
LazyAmountFromHeight, RollingDelta1m,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::ImportConfig;
|
use super::ImportConfig;
|
||||||
@@ -15,8 +15,8 @@ use super::ImportConfig;
|
|||||||
/// Supply metrics for a cohort.
|
/// Supply metrics for a cohort.
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct SupplyMetrics<M: StorageMode = Rw> {
|
pub struct SupplyMetrics<M: StorageMode = Rw> {
|
||||||
pub total: ValueFromHeight<M>,
|
pub total: AmountFromHeight<M>,
|
||||||
pub halved: LazyValueFromHeight,
|
pub halved: LazyAmountFromHeight,
|
||||||
pub delta: RollingDelta1m<Sats, SatsSigned, M>,
|
pub delta: RollingDelta1m<Sats, SatsSigned, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ impl SupplyMetrics {
|
|||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
let supply = cfg.import("supply", Version::ZERO)?;
|
let supply = cfg.import("supply", Version::ZERO)?;
|
||||||
|
|
||||||
let supply_halved = LazyValueFromHeight::from_block_source::<
|
let supply_halved = LazyAmountFromHeight::from_block_source::<
|
||||||
HalveSats,
|
HalveSats,
|
||||||
HalveSatsToBitcoin,
|
HalveSatsToBitcoin,
|
||||||
HalveCents,
|
HalveCents,
|
||||||
@@ -54,8 +54,8 @@ impl SupplyMetrics {
|
|||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
vec![
|
vec![
|
||||||
&mut self.total.base.sats.height as &mut dyn AnyStoredVec,
|
&mut self.total.sats.height as &mut dyn AnyStoredVec,
|
||||||
&mut self.total.base.cents.height as &mut dyn AnyStoredVec,
|
&mut self.total.cents.height as &mut dyn AnyStoredVec,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ impl SupplyMetrics {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.delta.compute(
|
self.delta.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1m_ago,
|
&blocks.lookback.height_1m_ago,
|
||||||
&self.total.sats.height,
|
&self.total.sats.height,
|
||||||
exit,
|
exit,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
|||||||
|
|
||||||
use crate::prices;
|
use crate::prices;
|
||||||
|
|
||||||
use crate::internal::ValueFromHeight;
|
use crate::internal::AmountFromHeight;
|
||||||
|
|
||||||
use crate::distribution::{metrics::ImportConfig, state::UnrealizedState};
|
use crate::distribution::{metrics::ImportConfig, state::UnrealizedState};
|
||||||
|
|
||||||
/// Minimal unrealized metrics: supply in profit/loss only.
|
/// Minimal unrealized metrics: supply in profit/loss only.
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct UnrealizedMinimal<M: StorageMode = Rw> {
|
pub struct UnrealizedMinimal<M: StorageMode = Rw> {
|
||||||
pub supply_in_profit: ValueFromHeight<M>,
|
pub supply_in_profit: AmountFromHeight<M>,
|
||||||
pub supply_in_loss: ValueFromHeight<M>,
|
pub supply_in_loss: AmountFromHeight<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnrealizedMinimal {
|
impl UnrealizedMinimal {
|
||||||
@@ -46,10 +46,10 @@ impl UnrealizedMinimal {
|
|||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
vec![
|
vec![
|
||||||
&mut self.supply_in_profit.base.sats.height as &mut dyn AnyStoredVec,
|
&mut self.supply_in_profit.sats.height as &mut dyn AnyStoredVec,
|
||||||
&mut self.supply_in_profit.base.cents.height as &mut dyn AnyStoredVec,
|
&mut self.supply_in_profit.cents.height as &mut dyn AnyStoredVec,
|
||||||
&mut self.supply_in_loss.base.sats.height as &mut dyn AnyStoredVec,
|
&mut self.supply_in_loss.sats.height as &mut dyn AnyStoredVec,
|
||||||
&mut self.supply_in_loss.base.cents.height as &mut dyn AnyStoredVec,
|
&mut self.supply_in_loss.cents.height as &mut dyn AnyStoredVec,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,8 +59,8 @@ impl UnrealizedMinimal {
|
|||||||
others: &[&Self],
|
others: &[&Self],
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
sum_others!(self, starting_indexes, others, exit; supply_in_profit.base.sats.height);
|
sum_others!(self, starting_indexes, others, exit; supply_in_profit.sats.height);
|
||||||
sum_others!(self, starting_indexes, others, exit; supply_in_loss.base.sats.height);
|
sum_others!(self, starting_indexes, others, exit; supply_in_loss.sats.height);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
|
|
||||||
self.address_activity
|
self.address_activity
|
||||||
.compute_rest(starting_indexes.height, &window_starts, exit)?;
|
.compute_rest(starting_indexes.height, &window_starts, exit)?;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ impl Vecs {
|
|||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
self.0
|
self.0
|
||||||
.compute(starting_indexes.height, &window_starts, exit, |full| {
|
.compute(starting_indexes.height, &window_starts, exit, |full| {
|
||||||
full.compute_with_skip(
|
full.compute_with_skip(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Value type with height-level data only (no period-derived views).
|
//! Amount type with height-level data only (no period-derived views).
|
||||||
//!
|
//!
|
||||||
//! Stores sats and cents per index, plus lazy btc and usd transforms.
|
//! Stores sats and cents per index, plus lazy btc and usd transforms.
|
||||||
//! Use when period views are unnecessary (e.g., rolling windows provide windowed data).
|
//! Use when period views are unnecessary (e.g., rolling windows provide windowed data).
|
||||||
@@ -16,26 +16,23 @@ use crate::{
|
|||||||
prices,
|
prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
const VERSION: Version = Version::TWO; // Match ValueFromHeight versioning
|
const VERSION: Version = Version::TWO; // Match AmountFromHeight versioning
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Value<I: VecIndex, M: StorageMode = Rw> {
|
pub struct Amount<I: VecIndex, M: StorageMode = Rw> {
|
||||||
pub sats: M::Stored<EagerVec<PcoVec<I, Sats>>>,
|
pub sats: M::Stored<EagerVec<PcoVec<I, Sats>>>,
|
||||||
pub btc: LazyVecFrom1<I, Bitcoin, I, Sats>,
|
pub btc: LazyVecFrom1<I, Bitcoin, I, Sats>,
|
||||||
pub cents: M::Stored<EagerVec<PcoVec<I, Cents>>>,
|
pub cents: M::Stored<EagerVec<PcoVec<I, Cents>>>,
|
||||||
pub usd: LazyVecFrom1<I, Dollars, I, Cents>,
|
pub usd: LazyVecFrom1<I, Dollars, I, Cents>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value<Height> {
|
impl Amount<Height> {
|
||||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||||
let v = version + VERSION;
|
let v = version + VERSION;
|
||||||
|
|
||||||
let sats: EagerVec<PcoVec<Height, Sats>> = EagerVec::forced_import(db, name, v)?;
|
let sats: EagerVec<PcoVec<Height, Sats>> =
|
||||||
let btc = LazyVecFrom1::transformed::<SatsToBitcoin>(
|
EagerVec::forced_import(db, &format!("{name}_sats"), v)?;
|
||||||
&format!("{name}_btc"),
|
let btc = LazyVecFrom1::transformed::<SatsToBitcoin>(name, v, sats.read_only_boxed_clone());
|
||||||
v,
|
|
||||||
sats.read_only_boxed_clone(),
|
|
||||||
);
|
|
||||||
let cents: EagerVec<PcoVec<Height, Cents>> =
|
let cents: EagerVec<PcoVec<Height, Cents>> =
|
||||||
EagerVec::forced_import(db, &format!("{name}_cents"), v)?;
|
EagerVec::forced_import(db, &format!("{name}_cents"), v)?;
|
||||||
let usd = LazyVecFrom1::transformed::<CentsUnsignedToDollars>(
|
let usd = LazyVecFrom1::transformed::<CentsUnsignedToDollars>(
|
||||||
@@ -2,20 +2,20 @@ use brk_traversable::Traversable;
|
|||||||
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
||||||
use vecdb::{LazyVecFrom1, ReadableCloneableVec, UnaryTransform, VecIndex};
|
use vecdb::{LazyVecFrom1, ReadableCloneableVec, UnaryTransform, VecIndex};
|
||||||
|
|
||||||
use crate::internal::ValueFromHeight;
|
use crate::internal::AmountFromHeight;
|
||||||
|
|
||||||
/// Fully lazy value type at height level.
|
/// Fully lazy value type at height level.
|
||||||
///
|
///
|
||||||
/// All fields are lazy transforms from existing sources - no storage.
|
/// All fields are lazy transforms from existing sources - no storage.
|
||||||
#[derive(Clone, Traversable)]
|
#[derive(Clone, Traversable)]
|
||||||
pub struct LazyValue<I: VecIndex> {
|
pub struct LazyAmount<I: VecIndex> {
|
||||||
pub sats: LazyVecFrom1<I, Sats, I, Sats>,
|
pub sats: LazyVecFrom1<I, Sats, I, Sats>,
|
||||||
pub btc: LazyVecFrom1<I, Bitcoin, I, Sats>,
|
pub btc: LazyVecFrom1<I, Bitcoin, I, Sats>,
|
||||||
pub cents: LazyVecFrom1<I, Cents, I, Cents>,
|
pub cents: LazyVecFrom1<I, Cents, I, Cents>,
|
||||||
pub usd: LazyVecFrom1<I, Dollars, I, Dollars>,
|
pub usd: LazyVecFrom1<I, Dollars, I, Dollars>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LazyValue<Height> {
|
impl LazyAmount<Height> {
|
||||||
pub(crate) fn from_block_source<
|
pub(crate) fn from_block_source<
|
||||||
SatsTransform,
|
SatsTransform,
|
||||||
BitcoinTransform,
|
BitcoinTransform,
|
||||||
@@ -23,7 +23,7 @@ impl LazyValue<Height> {
|
|||||||
DollarsTransform,
|
DollarsTransform,
|
||||||
>(
|
>(
|
||||||
name: &str,
|
name: &str,
|
||||||
source: &ValueFromHeight,
|
source: &AmountFromHeight,
|
||||||
version: Version,
|
version: Version,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
@@ -33,13 +33,13 @@ impl LazyValue<Height> {
|
|||||||
DollarsTransform: UnaryTransform<Dollars, Dollars>,
|
DollarsTransform: UnaryTransform<Dollars, Dollars>,
|
||||||
{
|
{
|
||||||
let sats = LazyVecFrom1::transformed::<SatsTransform>(
|
let sats = LazyVecFrom1::transformed::<SatsTransform>(
|
||||||
name,
|
&format!("{name}_sats"),
|
||||||
version,
|
version,
|
||||||
source.sats.height.read_only_boxed_clone(),
|
source.sats.height.read_only_boxed_clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let btc = LazyVecFrom1::transformed::<BitcoinTransform>(
|
let btc = LazyVecFrom1::transformed::<BitcoinTransform>(
|
||||||
&format!("{name}_btc"),
|
name,
|
||||||
version,
|
version,
|
||||||
source.sats.height.read_only_boxed_clone(),
|
source.sats.height.read_only_boxed_clone(),
|
||||||
);
|
);
|
||||||
@@ -14,7 +14,7 @@ pub struct DistributionStats<A> {
|
|||||||
|
|
||||||
impl<A> DistributionStats<A> {
|
impl<A> DistributionStats<A> {
|
||||||
pub const SUFFIXES: [&'static str; 8] = [
|
pub const SUFFIXES: [&'static str; 8] = [
|
||||||
"average", "min", "max", "p10", "p25", "median", "p75", "p90",
|
"average", "min", "max", "pct10", "pct25", "median", "pct75", "pct90",
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn try_from_fn<E>(
|
pub fn try_from_fn<E>(
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ use brk_traversable::Traversable;
|
|||||||
use brk_types::{Bitcoin, Cents, Dollars, Sats, Version};
|
use brk_types::{Bitcoin, Cents, Dollars, Sats, Version};
|
||||||
use vecdb::UnaryTransform;
|
use vecdb::UnaryTransform;
|
||||||
|
|
||||||
use crate::internal::{LazyHeightDerived, ValueFromHeight};
|
use crate::internal::{AmountFromHeight, LazyHeightDerived};
|
||||||
|
|
||||||
#[derive(Clone, Traversable)]
|
#[derive(Clone, Traversable)]
|
||||||
pub struct LazyValueHeightDerived {
|
pub struct LazyAmountHeightDerived {
|
||||||
pub sats: LazyHeightDerived<Sats, Sats>,
|
pub sats: LazyHeightDerived<Sats, Sats>,
|
||||||
pub btc: LazyHeightDerived<Bitcoin, Sats>,
|
pub btc: LazyHeightDerived<Bitcoin, Sats>,
|
||||||
pub cents: LazyHeightDerived<Cents, Cents>,
|
pub cents: LazyHeightDerived<Cents, Cents>,
|
||||||
pub usd: LazyHeightDerived<Dollars, Dollars>,
|
pub usd: LazyHeightDerived<Dollars, Dollars>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LazyValueHeightDerived {
|
impl LazyAmountHeightDerived {
|
||||||
pub(crate) fn from_block_source<
|
pub(crate) fn from_block_source<
|
||||||
SatsTransform,
|
SatsTransform,
|
||||||
BitcoinTransform,
|
BitcoinTransform,
|
||||||
@@ -20,7 +20,7 @@ impl LazyValueHeightDerived {
|
|||||||
DollarsTransform,
|
DollarsTransform,
|
||||||
>(
|
>(
|
||||||
name: &str,
|
name: &str,
|
||||||
source: &ValueFromHeight,
|
source: &AmountFromHeight,
|
||||||
version: Version,
|
version: Version,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
@@ -30,13 +30,13 @@ impl LazyValueHeightDerived {
|
|||||||
DollarsTransform: UnaryTransform<Dollars, Dollars>,
|
DollarsTransform: UnaryTransform<Dollars, Dollars>,
|
||||||
{
|
{
|
||||||
let sats = LazyHeightDerived::from_derived_computed::<SatsTransform>(
|
let sats = LazyHeightDerived::from_derived_computed::<SatsTransform>(
|
||||||
name,
|
&format!("{name}_sats"),
|
||||||
version,
|
version,
|
||||||
&source.sats.rest,
|
&source.sats.rest,
|
||||||
);
|
);
|
||||||
|
|
||||||
let btc = LazyHeightDerived::from_derived_computed::<BitcoinTransform>(
|
let btc = LazyHeightDerived::from_derived_computed::<BitcoinTransform>(
|
||||||
&format!("{name}_btc"),
|
name,
|
||||||
version,
|
version,
|
||||||
&source.sats.rest,
|
&source.sats.rest,
|
||||||
);
|
);
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
mod full;
|
mod full;
|
||||||
mod last;
|
mod last;
|
||||||
mod lazy_last;
|
mod lazy_last;
|
||||||
mod lazy_value;
|
mod lazy_amount;
|
||||||
mod map_option;
|
mod map_option;
|
||||||
mod transform_last;
|
mod transform_last;
|
||||||
|
|
||||||
pub use full::*;
|
pub use full::*;
|
||||||
pub use last::*;
|
pub use last::*;
|
||||||
pub use lazy_last::*;
|
pub use lazy_last::*;
|
||||||
pub use lazy_value::*;
|
pub use lazy_amount::*;
|
||||||
pub use map_option::*;
|
pub use map_option::*;
|
||||||
pub use transform_last::*;
|
pub use transform_last::*;
|
||||||
|
|||||||
@@ -5,19 +5,19 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{ByUnit, SatsToCents},
|
internal::{AmountFromHeight, SatsToCents},
|
||||||
prices,
|
prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct ValueFromHeightCumulative<M: StorageMode = Rw> {
|
pub struct AmountFromHeightCumulative<M: StorageMode = Rw> {
|
||||||
pub base: ByUnit<M>,
|
pub base: AmountFromHeight<M>,
|
||||||
pub cumulative: ByUnit<M>,
|
pub cumulative: AmountFromHeight<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERSION: Version = Version::ONE;
|
const VERSION: Version = Version::ONE;
|
||||||
|
|
||||||
impl ValueFromHeightCumulative {
|
impl AmountFromHeightCumulative {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -27,8 +27,13 @@ impl ValueFromHeightCumulative {
|
|||||||
let v = version + VERSION;
|
let v = version + VERSION;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
base: ByUnit::forced_import(db, name, v, indexes)?,
|
base: AmountFromHeight::forced_import(db, name, v, indexes)?,
|
||||||
cumulative: ByUnit::forced_import(db, &format!("{name}_cumulative"), v, indexes)?,
|
cumulative: AmountFromHeight::forced_import(
|
||||||
|
db,
|
||||||
|
&format!("{name}_cumulative"),
|
||||||
|
v,
|
||||||
|
indexes,
|
||||||
|
)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5,20 +5,20 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{ByUnit, RollingSumByUnit, SatsToCents, WindowStarts},
|
internal::{AmountFromHeight, RollingSumAmountFromHeight, SatsToCents, WindowStarts},
|
||||||
prices,
|
prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct ValueFromHeightCumulativeSum<M: StorageMode = Rw> {
|
pub struct AmountFromHeightCumulativeSum<M: StorageMode = Rw> {
|
||||||
pub base: ByUnit<M>,
|
pub base: AmountFromHeight<M>,
|
||||||
pub cumulative: ByUnit<M>,
|
pub cumulative: AmountFromHeight<M>,
|
||||||
pub sum: RollingSumByUnit<M>,
|
pub sum: RollingSumAmountFromHeight<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERSION: Version = Version::TWO;
|
const VERSION: Version = Version::TWO;
|
||||||
|
|
||||||
impl ValueFromHeightCumulativeSum {
|
impl AmountFromHeightCumulativeSum {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -28,9 +28,14 @@ impl ValueFromHeightCumulativeSum {
|
|||||||
let v = version + VERSION;
|
let v = version + VERSION;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
base: ByUnit::forced_import(db, name, v, indexes)?,
|
base: AmountFromHeight::forced_import(db, name, v, indexes)?,
|
||||||
cumulative: ByUnit::forced_import(db, &format!("{name}_cumulative"), v, indexes)?,
|
cumulative: AmountFromHeight::forced_import(
|
||||||
sum: RollingSumByUnit::forced_import(db, name, v, indexes)?,
|
db,
|
||||||
|
&format!("{name}_cumulative"),
|
||||||
|
v,
|
||||||
|
indexes,
|
||||||
|
)?,
|
||||||
|
sum: RollingSumAmountFromHeight::forced_import(db, name, v, indexes)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5,21 +5,21 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{ByUnit, RollingFullByUnit, SatsToCents, WindowStarts},
|
internal::{AmountFromHeight, RollingFullAmountFromHeight, SatsToCents, WindowStarts},
|
||||||
prices,
|
prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct ValueFromHeightFull<M: StorageMode = Rw> {
|
pub struct AmountFromHeightFull<M: StorageMode = Rw> {
|
||||||
pub base: ByUnit<M>,
|
pub base: AmountFromHeight<M>,
|
||||||
pub cumulative: ByUnit<M>,
|
pub cumulative: AmountFromHeight<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub rolling: RollingFullByUnit<M>,
|
pub rolling: RollingFullAmountFromHeight<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERSION: Version = Version::TWO;
|
const VERSION: Version = Version::TWO;
|
||||||
|
|
||||||
impl ValueFromHeightFull {
|
impl AmountFromHeightFull {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -29,9 +29,14 @@ impl ValueFromHeightFull {
|
|||||||
let v = version + VERSION;
|
let v = version + VERSION;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
base: ByUnit::forced_import(db, name, v, indexes)?,
|
base: AmountFromHeight::forced_import(db, name, v, indexes)?,
|
||||||
cumulative: ByUnit::forced_import(db, &format!("{name}_cumulative"), v, indexes)?,
|
cumulative: AmountFromHeight::forced_import(
|
||||||
rolling: RollingFullByUnit::forced_import(db, name, v, indexes)?,
|
db,
|
||||||
|
&format!("{name}_cumulative"),
|
||||||
|
v,
|
||||||
|
indexes,
|
||||||
|
)?,
|
||||||
|
rolling: RollingFullAmountFromHeight::forced_import(db, name, v, indexes)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
//! Lazy value wrapper for ValueFromHeight - all transforms are lazy.
|
//! Lazy value wrapper for AmountFromHeight - all transforms are lazy.
|
||||||
|
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::UnaryTransform;
|
use vecdb::UnaryTransform;
|
||||||
|
|
||||||
use crate::internal::{LazyValue, LazyValueHeightDerived, ValueFromHeight};
|
use crate::internal::{AmountFromHeight, LazyAmount, LazyAmountHeightDerived};
|
||||||
|
|
||||||
/// Lazy value wrapper with height + all derived last transforms from ValueFromHeight.
|
/// Lazy value wrapper with height + all derived last transforms from AmountFromHeight.
|
||||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
#[traversable(merge)]
|
||||||
pub struct LazyValueFromHeight {
|
pub struct LazyAmountFromHeight {
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub height: LazyValue<Height>,
|
pub height: LazyAmount<Height>,
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub rest: Box<LazyValueHeightDerived>,
|
pub rest: Box<LazyAmountHeightDerived>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LazyValueFromHeight {
|
impl LazyAmountFromHeight {
|
||||||
pub(crate) fn from_block_source<
|
pub(crate) fn from_block_source<
|
||||||
SatsTransform,
|
SatsTransform,
|
||||||
BitcoinTransform,
|
BitcoinTransform,
|
||||||
@@ -27,7 +27,7 @@ impl LazyValueFromHeight {
|
|||||||
DollarsTransform,
|
DollarsTransform,
|
||||||
>(
|
>(
|
||||||
name: &str,
|
name: &str,
|
||||||
source: &ValueFromHeight,
|
source: &AmountFromHeight,
|
||||||
version: Version,
|
version: Version,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
@@ -36,14 +36,14 @@ impl LazyValueFromHeight {
|
|||||||
CentsTransform: UnaryTransform<Cents, Cents>,
|
CentsTransform: UnaryTransform<Cents, Cents>,
|
||||||
DollarsTransform: UnaryTransform<Dollars, Dollars>,
|
DollarsTransform: UnaryTransform<Dollars, Dollars>,
|
||||||
{
|
{
|
||||||
let height = LazyValue::from_block_source::<
|
let height = LazyAmount::from_block_source::<
|
||||||
SatsTransform,
|
SatsTransform,
|
||||||
BitcoinTransform,
|
BitcoinTransform,
|
||||||
CentsTransform,
|
CentsTransform,
|
||||||
DollarsTransform,
|
DollarsTransform,
|
||||||
>(name, source, version);
|
>(name, source, version);
|
||||||
|
|
||||||
let rest = LazyValueHeightDerived::from_block_source::<
|
let rest = LazyAmountHeightDerived::from_block_source::<
|
||||||
SatsTransform,
|
SatsTransform,
|
||||||
BitcoinTransform,
|
BitcoinTransform,
|
||||||
CentsTransform,
|
CentsTransform,
|
||||||
122
crates/brk_computer/src/internal/from_height/amount/mod.rs
Normal file
122
crates/brk_computer/src/internal/from_height/amount/mod.rs
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
mod cumulative;
|
||||||
|
mod cumulative_sum;
|
||||||
|
mod full;
|
||||||
|
mod lazy;
|
||||||
|
mod rolling;
|
||||||
|
mod rolling_full;
|
||||||
|
mod rolling_sum;
|
||||||
|
|
||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
||||||
|
use vecdb::{AnyVec, Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
indexes,
|
||||||
|
internal::{
|
||||||
|
CentsUnsignedToDollars, ComputedFromHeight, LazyFromHeight, SatsToBitcoin, SatsToCents,
|
||||||
|
Windows,
|
||||||
|
},
|
||||||
|
prices,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub use cumulative::*;
|
||||||
|
pub use cumulative_sum::*;
|
||||||
|
pub use full::*;
|
||||||
|
pub use lazy::*;
|
||||||
|
pub use rolling::*;
|
||||||
|
pub use rolling_full::*;
|
||||||
|
pub use rolling_sum::*;
|
||||||
|
|
||||||
|
#[derive(Traversable)]
|
||||||
|
pub struct AmountFromHeight<M: StorageMode = Rw> {
|
||||||
|
pub sats: ComputedFromHeight<Sats, M>,
|
||||||
|
pub btc: LazyFromHeight<Bitcoin, Sats>,
|
||||||
|
pub cents: ComputedFromHeight<Cents, M>,
|
||||||
|
pub usd: LazyFromHeight<Dollars, Cents>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AmountFromHeight {
|
||||||
|
pub(crate) fn forced_import(
|
||||||
|
db: &Database,
|
||||||
|
name: &str,
|
||||||
|
version: Version,
|
||||||
|
indexes: &indexes::Vecs,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let sats =
|
||||||
|
ComputedFromHeight::forced_import(db, &format!("{name}_sats"), version, indexes)?;
|
||||||
|
|
||||||
|
let btc = LazyFromHeight::from_computed::<SatsToBitcoin>(
|
||||||
|
name,
|
||||||
|
version,
|
||||||
|
sats.height.read_only_boxed_clone(),
|
||||||
|
&sats,
|
||||||
|
);
|
||||||
|
|
||||||
|
let cents =
|
||||||
|
ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?;
|
||||||
|
|
||||||
|
let usd = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
|
||||||
|
&format!("{name}_usd"),
|
||||||
|
version,
|
||||||
|
cents.height.read_only_boxed_clone(),
|
||||||
|
¢s,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
sats,
|
||||||
|
btc,
|
||||||
|
cents,
|
||||||
|
usd,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||||
|
self.sats.height.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute(
|
||||||
|
&mut self,
|
||||||
|
prices: &prices::Vecs,
|
||||||
|
max_from: Height,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.cents.compute_binary::<Sats, Cents, SatsToCents>(
|
||||||
|
max_from,
|
||||||
|
&self.sats.height,
|
||||||
|
&prices.price.cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_rolling_sum(
|
||||||
|
&mut self,
|
||||||
|
max_from: Height,
|
||||||
|
window_starts: &impl ReadableVec<Height, Height>,
|
||||||
|
sats_source: &impl ReadableVec<Height, Sats>,
|
||||||
|
cents_source: &impl ReadableVec<Height, Cents>,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.sats
|
||||||
|
.height
|
||||||
|
.compute_rolling_sum(max_from, window_starts, sats_source, exit)?;
|
||||||
|
self.cents
|
||||||
|
.height
|
||||||
|
.compute_rolling_sum(max_from, window_starts, cents_source, exit)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Windows<AmountFromHeight> {
|
||||||
|
pub(crate) fn forced_import(
|
||||||
|
db: &Database,
|
||||||
|
name: &str,
|
||||||
|
version: Version,
|
||||||
|
indexes: &indexes::Vecs,
|
||||||
|
) -> Result<Self> {
|
||||||
|
Windows::try_from_fn(|suffix| {
|
||||||
|
AmountFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//! Value type for Height + Rolling pattern.
|
//! Value type for Height + Rolling pattern.
|
||||||
//!
|
//!
|
||||||
//! Combines Value (sats/btc/usd per height, no period views) with
|
//! Combines Value (sats/btc/usd per height, no period views) with
|
||||||
//! ValueFromHeightWindows (rolling sums across 4 windows).
|
//! AmountFromHeightWindows (rolling sums across 4 windows).
|
||||||
|
|
||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
@@ -11,21 +11,21 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{Value, ValueFromHeightWindows, WindowStarts},
|
internal::{Amount, AmountFromHeightWindows, WindowStarts},
|
||||||
prices,
|
prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
pub struct ValueFromHeightRolling<M: StorageMode = Rw> {
|
pub struct AmountFromHeightRolling<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub value: Value<Height, M>,
|
pub amount: Amount<Height, M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub rolling: ValueFromHeightWindows<M>,
|
pub rolling: AmountFromHeightWindows<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValueFromHeightRolling {
|
impl AmountFromHeightRolling {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -33,8 +33,8 @@ impl ValueFromHeightRolling {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
value: Value::forced_import(db, name, version)?,
|
amount: Amount::forced_import(db, name, version)?,
|
||||||
rolling: ValueFromHeightWindows::forced_import(db, name, version, indexes)?,
|
rolling: AmountFromHeightWindows::forced_import(db, name, version, indexes)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,13 +47,13 @@ impl ValueFromHeightRolling {
|
|||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
|
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
compute_sats(&mut self.value.sats)?;
|
compute_sats(&mut self.amount.sats)?;
|
||||||
self.value.compute_cents(prices, max_from, exit)?;
|
self.amount.compute_cents(prices, max_from, exit)?;
|
||||||
self.rolling.compute_rolling_sum(
|
self.rolling.compute_rolling_sum(
|
||||||
max_from,
|
max_from,
|
||||||
windows,
|
windows,
|
||||||
&self.value.sats,
|
&self.amount.sats,
|
||||||
&self.value.cents,
|
&self.amount.cents,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -7,18 +7,18 @@ use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
|
|||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{
|
internal::{
|
||||||
ByUnit, DistributionStats, WindowStarts, Windows, compute_rolling_distribution_from_starts,
|
AmountFromHeight, DistributionStats, WindowStarts, Windows, compute_rolling_distribution_from_starts,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// One window slot: sum + 8 distribution stats, each a ByUnit.
|
/// One window slot: sum + 8 distribution stats, each a AmountFromHeight.
|
||||||
///
|
///
|
||||||
/// Tree: `sum.sats.height`, `average.sats.height`, etc.
|
/// Tree: `sum.sats.height`, `average.sats.height`, etc.
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct RollingFullSlot<M: StorageMode = Rw> {
|
pub struct RollingFullSlot<M: StorageMode = Rw> {
|
||||||
pub sum: ByUnit<M>,
|
pub sum: AmountFromHeight<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub distribution: DistributionStats<ByUnit<M>>,
|
pub distribution: DistributionStats<AmountFromHeight<M>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RollingFullSlot {
|
impl RollingFullSlot {
|
||||||
@@ -29,9 +29,9 @@ impl RollingFullSlot {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
sum: ByUnit::forced_import(db, &format!("{name}_sum"), version, indexes)?,
|
sum: AmountFromHeight::forced_import(db, &format!("{name}_sum"), version, indexes)?,
|
||||||
distribution: DistributionStats::try_from_fn(|suffix| {
|
distribution: DistributionStats::try_from_fn(|suffix| {
|
||||||
ByUnit::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
|
AmountFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
|
||||||
})?,
|
})?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -85,9 +85,9 @@ impl RollingFullSlot {
|
|||||||
/// Tree: `_24h.sum.sats.height`, `_24h.average.sats.height`, etc.
|
/// Tree: `_24h.sum.sats.height`, `_24h.average.sats.height`, etc.
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(transparent)]
|
#[traversable(transparent)]
|
||||||
pub struct RollingFullByUnit<M: StorageMode = Rw>(pub Windows<RollingFullSlot<M>>);
|
pub struct RollingFullAmountFromHeight<M: StorageMode = Rw>(pub Windows<RollingFullSlot<M>>);
|
||||||
|
|
||||||
impl RollingFullByUnit {
|
impl RollingFullAmountFromHeight {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -6,7 +6,7 @@ use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{ByUnit, WindowStarts, Windows},
|
internal::{AmountFromHeight, WindowStarts, Windows},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Rolling sum only, window-first then unit.
|
/// Rolling sum only, window-first then unit.
|
||||||
@@ -14,16 +14,16 @@ use crate::{
|
|||||||
/// Tree: `_24h.sats.height`, `_24h.btc.height`, etc.
|
/// Tree: `_24h.sats.height`, `_24h.btc.height`, etc.
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(transparent)]
|
#[traversable(transparent)]
|
||||||
pub struct RollingSumByUnit<M: StorageMode = Rw>(pub Windows<ByUnit<M>>);
|
pub struct RollingSumAmountFromHeight<M: StorageMode = Rw>(pub Windows<AmountFromHeight<M>>);
|
||||||
|
|
||||||
impl RollingSumByUnit {
|
impl RollingSumAmountFromHeight {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
name: &str,
|
name: &str,
|
||||||
version: Version,
|
version: Version,
|
||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self(Windows::<ByUnit>::forced_import(
|
Ok(Self(Windows::<AmountFromHeight>::forced_import(
|
||||||
db,
|
db,
|
||||||
&format!("{name}_sum"),
|
&format!("{name}_sum"),
|
||||||
version,
|
version,
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
mod rolling_full;
|
|
||||||
mod rolling_sum;
|
|
||||||
|
|
||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{Bitcoin, Cents, Dollars, Sats, Version};
|
|
||||||
use vecdb::{AnyVec, Database, ReadableCloneableVec, Rw, StorageMode};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
indexes,
|
|
||||||
internal::{
|
|
||||||
CentsUnsignedToDollars, ComputedFromHeight, LazyFromHeight, SatsToBitcoin, Windows,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use rolling_full::*;
|
|
||||||
pub use rolling_sum::*;
|
|
||||||
|
|
||||||
#[derive(Traversable)]
|
|
||||||
pub struct ByUnit<M: StorageMode = Rw> {
|
|
||||||
pub sats: ComputedFromHeight<Sats, M>,
|
|
||||||
pub btc: LazyFromHeight<Bitcoin, Sats>,
|
|
||||||
pub cents: ComputedFromHeight<Cents, M>,
|
|
||||||
pub usd: LazyFromHeight<Dollars, Cents>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ByUnit {
|
|
||||||
pub(crate) fn forced_import(
|
|
||||||
db: &Database,
|
|
||||||
name: &str,
|
|
||||||
version: Version,
|
|
||||||
indexes: &indexes::Vecs,
|
|
||||||
) -> Result<Self> {
|
|
||||||
let sats = ComputedFromHeight::forced_import(db, name, version, indexes)?;
|
|
||||||
|
|
||||||
let btc = LazyFromHeight::from_computed::<SatsToBitcoin>(
|
|
||||||
&format!("{name}_btc"),
|
|
||||||
version,
|
|
||||||
sats.height.read_only_boxed_clone(),
|
|
||||||
&sats,
|
|
||||||
);
|
|
||||||
|
|
||||||
let cents =
|
|
||||||
ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?;
|
|
||||||
|
|
||||||
let usd = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
|
|
||||||
&format!("{name}_usd"),
|
|
||||||
version,
|
|
||||||
cents.height.read_only_boxed_clone(),
|
|
||||||
¢s,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
sats,
|
|
||||||
btc,
|
|
||||||
cents,
|
|
||||||
usd,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
|
||||||
self.sats.height.len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Windows<ByUnit> {
|
|
||||||
pub(crate) fn forced_import(
|
|
||||||
db: &Database,
|
|
||||||
name: &str,
|
|
||||||
version: Version,
|
|
||||||
indexes: &indexes::Vecs,
|
|
||||||
) -> Result<Self> {
|
|
||||||
Windows::try_from_fn(|suffix| {
|
|
||||||
ByUnit::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -41,7 +41,7 @@ impl<C: CentsType> FiatFromHeight<C> {
|
|||||||
let cents =
|
let cents =
|
||||||
ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?;
|
ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?;
|
||||||
let usd = LazyFromHeight::from_computed::<C::ToDollars>(
|
let usd = LazyFromHeight::from_computed::<C::ToDollars>(
|
||||||
&format!("{name}_usd"),
|
name,
|
||||||
version,
|
version,
|
||||||
cents.height.read_only_boxed_clone(),
|
cents.height.read_only_boxed_clone(),
|
||||||
¢s,
|
¢s,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ impl<C: CentsType> LazyFiatFromHeight<C> {
|
|||||||
source,
|
source,
|
||||||
);
|
);
|
||||||
let usd = LazyFromHeight::from_computed::<C::ToDollars>(
|
let usd = LazyFromHeight::from_computed::<C::ToDollars>(
|
||||||
&format!("{name}_usd"),
|
name,
|
||||||
version,
|
version,
|
||||||
source.height.read_only_boxed_clone(),
|
source.height.read_only_boxed_clone(),
|
||||||
source,
|
source,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
mod base;
|
mod base;
|
||||||
mod by_unit;
|
mod amount;
|
||||||
mod computed;
|
mod computed;
|
||||||
mod constant;
|
mod constant;
|
||||||
mod fiat;
|
mod fiat;
|
||||||
@@ -10,10 +10,9 @@ mod percentiles;
|
|||||||
mod price;
|
mod price;
|
||||||
mod ratio;
|
mod ratio;
|
||||||
mod stddev;
|
mod stddev;
|
||||||
mod value;
|
|
||||||
|
|
||||||
pub use base::*;
|
pub use base::*;
|
||||||
pub use by_unit::*;
|
pub use amount::*;
|
||||||
pub use computed::*;
|
pub use computed::*;
|
||||||
pub use constant::*;
|
pub use constant::*;
|
||||||
pub use fiat::*;
|
pub use fiat::*;
|
||||||
@@ -24,4 +23,3 @@ pub use percentiles::*;
|
|||||||
pub use price::*;
|
pub use price::*;
|
||||||
pub use ratio::*;
|
pub use ratio::*;
|
||||||
pub use stddev::*;
|
pub use stddev::*;
|
||||||
pub use value::*;
|
|
||||||
|
|||||||
@@ -91,14 +91,14 @@ impl ComputedFromHeightRatioPercentiles {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.ratio_sma_1w.bps.height.compute_rolling_average(
|
self.ratio_sma_1w.bps.height.compute_rolling_average(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1w_ago,
|
&blocks.lookback.height_1w_ago,
|
||||||
ratio_source,
|
ratio_source,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.ratio_sma_1m.bps.height.compute_rolling_average(
|
self.ratio_sma_1m.bps.height.compute_rolling_average(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1m_ago,
|
&blocks.lookback.height_1m_ago,
|
||||||
ratio_source,
|
ratio_source,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ impl ComputedFromHeightStdDev {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let window_starts = blocks.count.start_vec(self.days);
|
let window_starts = blocks.lookback.start_vec(self.days);
|
||||||
|
|
||||||
self.sma.height.compute_rolling_average(
|
self.sma.height.compute_rolling_average(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{Cents, Height, Sats, Version};
|
|
||||||
use derive_more::{Deref, DerefMut};
|
|
||||||
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
indexes,
|
|
||||||
internal::{ByUnit, SatsToCents},
|
|
||||||
prices,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
|
||||||
#[traversable(transparent)]
|
|
||||||
pub struct ValueFromHeight<M: StorageMode = Rw> {
|
|
||||||
#[deref]
|
|
||||||
#[deref_mut]
|
|
||||||
pub base: ByUnit<M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const VERSION: Version = Version::TWO;
|
|
||||||
|
|
||||||
impl ValueFromHeight {
|
|
||||||
pub(crate) fn forced_import(
|
|
||||||
db: &Database,
|
|
||||||
name: &str,
|
|
||||||
version: Version,
|
|
||||||
indexes: &indexes::Vecs,
|
|
||||||
) -> Result<Self> {
|
|
||||||
let v = version + VERSION;
|
|
||||||
Ok(Self {
|
|
||||||
base: ByUnit::forced_import(db, name, v, indexes)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute(
|
|
||||||
&mut self,
|
|
||||||
prices: &prices::Vecs,
|
|
||||||
max_from: Height,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.base.cents.compute_binary::<Sats, Cents, SatsToCents>(
|
|
||||||
max_from,
|
|
||||||
&self.base.sats.height,
|
|
||||||
&prices.price.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rolling_sum(
|
|
||||||
&mut self,
|
|
||||||
max_from: Height,
|
|
||||||
window_starts: &impl ReadableVec<Height, Height>,
|
|
||||||
sats_source: &impl ReadableVec<Height, Sats>,
|
|
||||||
cents_source: &impl ReadableVec<Height, Cents>,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.base
|
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.compute_rolling_sum(max_from, window_starts, sats_source, exit)?;
|
|
||||||
self.base
|
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.compute_rolling_sum(max_from, window_starts, cents_source, exit)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
mod base;
|
|
||||||
mod cumulative;
|
|
||||||
mod cumulative_sum;
|
|
||||||
mod full;
|
|
||||||
mod lazy;
|
|
||||||
mod rolling;
|
|
||||||
|
|
||||||
pub use base::*;
|
|
||||||
pub use cumulative::*;
|
|
||||||
pub use cumulative_sum::*;
|
|
||||||
pub use full::*;
|
|
||||||
pub use lazy::*;
|
|
||||||
pub use rolling::*;
|
|
||||||
@@ -9,7 +9,7 @@ mod indexes;
|
|||||||
mod rolling;
|
mod rolling;
|
||||||
mod traits;
|
mod traits;
|
||||||
mod transform;
|
mod transform;
|
||||||
mod value;
|
mod amount;
|
||||||
|
|
||||||
pub(crate) use aggregate::*;
|
pub(crate) use aggregate::*;
|
||||||
pub(crate) use algo::*;
|
pub(crate) use algo::*;
|
||||||
@@ -22,4 +22,4 @@ pub(crate) use indexes::*;
|
|||||||
pub(crate) use rolling::*;
|
pub(crate) use rolling::*;
|
||||||
pub(crate) use traits::*;
|
pub(crate) use traits::*;
|
||||||
pub use transform::*;
|
pub use transform::*;
|
||||||
pub(crate) use value::*;
|
pub(crate) use amount::*;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! ValueFromHeightWindows - window-first ordering.
|
//! AmountFromHeightWindows - window-first ordering.
|
||||||
//!
|
//!
|
||||||
//! Access pattern: `coinbase_sum._24h.sats.height`
|
//! Access pattern: `coinbase_sum._24h.sats.height`
|
||||||
//! Each window (24h, 7d, 30d, 1y) contains sats (stored) + btc (lazy) + usd (stored).
|
//! Each window (24h, 7d, 30d, 1y) contains sats (stored) + btc (lazy) + usd (stored).
|
||||||
@@ -14,17 +14,17 @@ use brk_types::{Cents, Sats};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{ValueFromHeight, WindowStarts, Windows},
|
internal::{AmountFromHeight, WindowStarts, Windows},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Value rolling windows — window-first, currency-last.
|
/// Value rolling windows — window-first, currency-last.
|
||||||
///
|
///
|
||||||
/// Each window contains `ValueFromHeight` (sats + btc lazy + usd).
|
/// Each window contains `AmountFromHeight` (sats + btc lazy + usd).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(transparent)]
|
#[traversable(transparent)]
|
||||||
pub struct ValueFromHeightWindows<M: StorageMode = Rw>(pub Windows<ValueFromHeight<M>>);
|
pub struct AmountFromHeightWindows<M: StorageMode = Rw>(pub Windows<AmountFromHeight<M>>);
|
||||||
|
|
||||||
impl ValueFromHeightWindows {
|
impl AmountFromHeightWindows {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -32,7 +32,7 @@ impl ValueFromHeightWindows {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self(Windows::try_from_fn(|suffix| {
|
Ok(Self(Windows::try_from_fn(|suffix| {
|
||||||
ValueFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
|
AmountFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
|
||||||
})?))
|
})?))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
mod distribution;
|
mod distribution;
|
||||||
mod full;
|
mod full;
|
||||||
mod percent_windows;
|
mod percent_windows;
|
||||||
mod value_windows;
|
mod amount_windows;
|
||||||
mod windows;
|
mod windows;
|
||||||
|
|
||||||
pub use distribution::*;
|
pub use distribution::*;
|
||||||
pub use full::*;
|
pub use full::*;
|
||||||
pub use percent_windows::*;
|
pub use percent_windows::*;
|
||||||
pub use value_windows::*;
|
pub use amount_windows::*;
|
||||||
pub use windows::*;
|
pub use windows::*;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ impl Vecs {
|
|||||||
|
|
||||||
// DCA by period - stack (rolling sum via _start vecs)
|
// DCA by period - stack (rolling sum via _start vecs)
|
||||||
for (stack, days) in self.period_stack.iter_mut_with_days() {
|
for (stack, days) in self.period_stack.iter_mut_with_days() {
|
||||||
let window_starts = blocks.count.start_vec(days as usize);
|
let window_starts = blocks.lookback.start_vec(days as usize);
|
||||||
stack.sats.height.compute_rolling_sum(
|
stack.sats.height.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
window_starts,
|
window_starts,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use vecdb::{Database, ImportableVec};
|
|||||||
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod, Vecs};
|
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod, Vecs};
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{PercentFromHeight, Price, ValueFromHeight},
|
internal::{AmountFromHeight, PercentFromHeight, Price},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
@@ -15,7 +15,7 @@ impl Vecs {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let period_stack = ByDcaPeriod::try_new(|name, _days| {
|
let period_stack = ByDcaPeriod::try_new(|name, _days| {
|
||||||
ValueFromHeight::forced_import(db, &format!("dca_stack_{name}"), version, indexes)
|
AmountFromHeight::forced_import(db, &format!("dca_stack_{name}"), version, indexes)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let period_cost_basis = ByDcaPeriod::try_new(|name, _days| {
|
let period_cost_basis = ByDcaPeriod::try_new(|name, _days| {
|
||||||
@@ -31,7 +31,7 @@ impl Vecs {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
let period_lump_sum_stack = ByDcaPeriod::try_new(|name, _days| {
|
let period_lump_sum_stack = ByDcaPeriod::try_new(|name, _days| {
|
||||||
ValueFromHeight::forced_import(db, &format!("lump_sum_stack_{name}"), version, indexes)
|
AmountFromHeight::forced_import(db, &format!("lump_sum_stack_{name}"), version, indexes)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let period_lump_sum_return = ByDcaPeriod::try_new(|name, _days| {
|
let period_lump_sum_return = ByDcaPeriod::try_new(|name, _days| {
|
||||||
@@ -44,7 +44,7 @@ impl Vecs {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
let class_stack = ByDcaClass::try_new(|name, _year, _day1| {
|
let class_stack = ByDcaClass::try_new(|name, _year, _day1| {
|
||||||
ValueFromHeight::forced_import(db, &format!("dca_stack_{name}"), version, indexes)
|
AmountFromHeight::forced_import(db, &format!("dca_stack_{name}"), version, indexes)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let class_cost_basis = ByDcaClass::try_new(|name, _year, _day1| {
|
let class_cost_basis = ByDcaClass::try_new(|name, _year, _day1| {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use brk_types::{BasisPointsSigned32, Cents, Height, Sats};
|
|||||||
use vecdb::{EagerVec, PcoVec, Rw, StorageMode};
|
use vecdb::{EagerVec, PcoVec, Rw, StorageMode};
|
||||||
|
|
||||||
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod};
|
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod};
|
||||||
use crate::internal::{ComputedFromHeight, PercentFromHeight, Price, ValueFromHeight};
|
use crate::internal::{AmountFromHeight, ComputedFromHeight, PercentFromHeight, Price};
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
/// Per-height DCA sats contribution: sats_from_dca(close) on day boundaries, 0 otherwise.
|
/// Per-height DCA sats contribution: sats_from_dca(close) on day boundaries, 0 otherwise.
|
||||||
@@ -11,17 +11,17 @@ pub struct Vecs<M: StorageMode = Rw> {
|
|||||||
pub dca_sats_per_day: M::Stored<EagerVec<PcoVec<Height, Sats>>>,
|
pub dca_sats_per_day: M::Stored<EagerVec<PcoVec<Height, Sats>>>,
|
||||||
|
|
||||||
// DCA by period
|
// DCA by period
|
||||||
pub period_stack: ByDcaPeriod<ValueFromHeight<M>>,
|
pub period_stack: ByDcaPeriod<AmountFromHeight<M>>,
|
||||||
pub period_cost_basis: ByDcaPeriod<Price<ComputedFromHeight<Cents, M>>>,
|
pub period_cost_basis: ByDcaPeriod<Price<ComputedFromHeight<Cents, M>>>,
|
||||||
pub period_return: ByDcaPeriod<PercentFromHeight<BasisPointsSigned32, M>>,
|
pub period_return: ByDcaPeriod<PercentFromHeight<BasisPointsSigned32, M>>,
|
||||||
pub period_cagr: ByDcaCagr<PercentFromHeight<BasisPointsSigned32, M>>,
|
pub period_cagr: ByDcaCagr<PercentFromHeight<BasisPointsSigned32, M>>,
|
||||||
|
|
||||||
// Lump sum by period (for comparison with DCA)
|
// Lump sum by period (for comparison with DCA)
|
||||||
pub period_lump_sum_stack: ByDcaPeriod<ValueFromHeight<M>>,
|
pub period_lump_sum_stack: ByDcaPeriod<AmountFromHeight<M>>,
|
||||||
pub period_lump_sum_return: ByDcaPeriod<PercentFromHeight<BasisPointsSigned32, M>>,
|
pub period_lump_sum_return: ByDcaPeriod<PercentFromHeight<BasisPointsSigned32, M>>,
|
||||||
|
|
||||||
// DCA by year class
|
// DCA by year class
|
||||||
pub class_stack: ByDcaClass<ValueFromHeight<M>>,
|
pub class_stack: ByDcaClass<AmountFromHeight<M>>,
|
||||||
pub class_cost_basis: ByDcaClass<Price<ComputedFromHeight<Cents, M>>>,
|
pub class_cost_basis: ByDcaClass<Price<ComputedFromHeight<Cents, M>>>,
|
||||||
pub class_return: ByDcaClass<PercentFromHeight<BasisPointsSigned32, M>>,
|
pub class_return: ByDcaClass<PercentFromHeight<BasisPointsSigned32, M>>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ impl Vecs {
|
|||||||
|
|
||||||
self.stoch_d.bps.height.compute_rolling_average(
|
self.stoch_d.bps.height.compute_rolling_average(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_3d_ago,
|
&blocks.lookback.height_3d_ago,
|
||||||
&self.stoch_k.bps.height,
|
&self.stoch_k.bps.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ pub(super) fn compute(
|
|||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let close = &prices.price.usd.height;
|
let close = &prices.price.usd.height;
|
||||||
let ws_fast = blocks.count.start_vec(fast_days);
|
let ws_fast = blocks.lookback.start_vec(fast_days);
|
||||||
let ws_slow = blocks.count.start_vec(slow_days);
|
let ws_slow = blocks.lookback.start_vec(slow_days);
|
||||||
let ws_signal = blocks.count.start_vec(signal_days);
|
let ws_signal = blocks.lookback.start_vec(signal_days);
|
||||||
|
|
||||||
chain
|
chain
|
||||||
.ema_fast
|
.ema_fast
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ pub(super) fn compute(
|
|||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let ws_rma = blocks.count.start_vec(rma_days);
|
let ws_rma = blocks.lookback.start_vec(rma_days);
|
||||||
let ws_sma = blocks.count.start_vec(stoch_sma_days);
|
let ws_sma = blocks.lookback.start_vec(stoch_sma_days);
|
||||||
|
|
||||||
// Gains = max(return, 0)
|
// Gains = max(return, 0)
|
||||||
chain.gains.height.compute_transform(
|
chain.gains.height.compute_transform(
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ impl Vecs {
|
|||||||
let price = &prices.price.cents.height;
|
let price = &prices.price.cents.height;
|
||||||
|
|
||||||
for (price_lookback, days) in self.price_lookback.iter_mut_with_days() {
|
for (price_lookback, days) in self.price_lookback.iter_mut_with_days() {
|
||||||
let window_starts = blocks.count.start_vec(days as usize);
|
let window_starts = blocks.lookback.start_vec(days as usize);
|
||||||
price_lookback.cents.height.compute_lookback(
|
price_lookback.cents.height.compute_lookback(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
window_starts,
|
window_starts,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ impl Vecs {
|
|||||||
(&mut self.price_sma_200w, 200 * 7),
|
(&mut self.price_sma_200w, 200 * 7),
|
||||||
(&mut self.price_sma_4y, 4 * 365),
|
(&mut self.price_sma_4y, 4 * 365),
|
||||||
] {
|
] {
|
||||||
let window_starts = blocks.count.start_vec(period);
|
let window_starts = blocks.lookback.start_vec(period);
|
||||||
sma.compute_all(prices, starting_indexes, exit, |v| {
|
sma.compute_all(prices, starting_indexes, exit, |v| {
|
||||||
v.compute_rolling_average(starting_indexes.height, window_starts, close, exit)?;
|
v.compute_rolling_average(starting_indexes.height, window_starts, close, exit)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -58,7 +58,7 @@ impl Vecs {
|
|||||||
(&mut self.price_ema_200w, 200 * 7),
|
(&mut self.price_ema_200w, 200 * 7),
|
||||||
(&mut self.price_ema_4y, 4 * 365),
|
(&mut self.price_ema_4y, 4 * 365),
|
||||||
] {
|
] {
|
||||||
let window_starts = blocks.count.start_vec(period);
|
let window_starts = blocks.lookback.start_vec(period);
|
||||||
ema.compute_all(prices, starting_indexes, exit, |v| {
|
ema.compute_all(prices, starting_indexes, exit, |v| {
|
||||||
v.compute_rolling_ema(starting_indexes.height, window_starts, close, exit)?;
|
v.compute_rolling_ema(starting_indexes.height, window_starts, close, exit)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -19,22 +19,22 @@ impl Vecs {
|
|||||||
(
|
(
|
||||||
&mut self.price_min_1w.cents.height,
|
&mut self.price_min_1w.cents.height,
|
||||||
&mut self.price_max_1w.cents.height,
|
&mut self.price_max_1w.cents.height,
|
||||||
&blocks.count.height_1w_ago,
|
&blocks.lookback.height_1w_ago,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
&mut self.price_min_2w.cents.height,
|
&mut self.price_min_2w.cents.height,
|
||||||
&mut self.price_max_2w.cents.height,
|
&mut self.price_max_2w.cents.height,
|
||||||
&blocks.count.height_2w_ago,
|
&blocks.lookback.height_2w_ago,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
&mut self.price_min_1m.cents.height,
|
&mut self.price_min_1m.cents.height,
|
||||||
&mut self.price_max_1m.cents.height,
|
&mut self.price_max_1m.cents.height,
|
||||||
&blocks.count.height_1m_ago,
|
&blocks.lookback.height_1m_ago,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
&mut self.price_min_1y.cents.height,
|
&mut self.price_min_1y.cents.height,
|
||||||
&mut self.price_max_1y.cents.height,
|
&mut self.price_max_1y.cents.height,
|
||||||
&blocks.count.height_1y_ago,
|
&blocks.lookback.height_1y_ago,
|
||||||
),
|
),
|
||||||
] {
|
] {
|
||||||
min_vec.compute_rolling_min_from_starts(
|
min_vec.compute_rolling_min_from_starts(
|
||||||
@@ -75,7 +75,7 @@ impl Vecs {
|
|||||||
// 2w rolling sum of true range
|
// 2w rolling sum of true range
|
||||||
self.price_true_range_sum_2w.height.compute_rolling_sum(
|
self.price_true_range_sum_2w.height.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_2w_ago,
|
&blocks.lookback.height_2w_ago,
|
||||||
&self.price_true_range.height,
|
&self.price_true_range.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
@@ -88,7 +88,7 @@ impl Vecs {
|
|||||||
&self.price_true_range_sum_2w.height,
|
&self.price_true_range_sum_2w.height,
|
||||||
&self.price_max_2w.cents.height,
|
&self.price_max_2w.cents.height,
|
||||||
&self.price_min_2w.cents.height,
|
&self.price_min_2w.cents.height,
|
||||||
&blocks.count.height_2w_ago,
|
&blocks.lookback.height_2w_ago,
|
||||||
|(h, tr_sum, max, min, window_start, ..)| {
|
|(h, tr_sum, max, min, window_start, ..)| {
|
||||||
let range = f64::from(max) - f64::from(min);
|
let range = f64::from(max) - f64::from(min);
|
||||||
let n = (h.to_usize() - window_start.to_usize() + 1) as f32;
|
let n = (h.to_usize() - window_start.to_usize() + 1) as f32;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ impl Vecs {
|
|||||||
self.rewards.compute(
|
self.rewards.compute(
|
||||||
indexer,
|
indexer,
|
||||||
indexes,
|
indexes,
|
||||||
&blocks.count,
|
&blocks.lookback,
|
||||||
&transactions.fees,
|
&transactions.fees,
|
||||||
prices,
|
prices,
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
@@ -31,6 +31,7 @@ impl Vecs {
|
|||||||
|
|
||||||
self.hashrate.compute(
|
self.hashrate.compute(
|
||||||
&blocks.count,
|
&blocks.count,
|
||||||
|
&blocks.lookback,
|
||||||
&blocks.difficulty,
|
&blocks.difficulty,
|
||||||
&self.rewards.coinbase.sum._24h.sats.height,
|
&self.rewards.coinbase.sum._24h.sats.height,
|
||||||
&self.rewards.coinbase.sum._24h.usd.height,
|
&self.rewards.coinbase.sum._24h.usd.height,
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
count_vecs: &blocks::CountVecs,
|
count_vecs: &blocks::CountVecs,
|
||||||
|
lookback: &blocks::LookbackVecs,
|
||||||
difficulty_vecs: &blocks::DifficultyVecs,
|
difficulty_vecs: &blocks::DifficultyVecs,
|
||||||
coinbase_sats_24h_sum: &impl ReadableVec<Height, Sats>,
|
coinbase_sats_24h_sum: &impl ReadableVec<Height, Sats>,
|
||||||
coinbase_usd_24h_sum: &impl ReadableVec<Height, Dollars>,
|
coinbase_usd_24h_sum: &impl ReadableVec<Height, Dollars>,
|
||||||
@@ -20,7 +22,7 @@ impl Vecs {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.hash_rate.height.compute_transform2(
|
self.hash_rate.height.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&count_vecs.block_count_sum._24h.height,
|
&count_vecs.block_count.sum._24h.height,
|
||||||
&difficulty_vecs.as_hash.height,
|
&difficulty_vecs.as_hash.height,
|
||||||
|(i, block_count_sum, difficulty_as_hash, ..)| {
|
|(i, block_count_sum, difficulty_as_hash, ..)| {
|
||||||
(
|
(
|
||||||
@@ -36,10 +38,10 @@ impl Vecs {
|
|||||||
|
|
||||||
let hash_rate = &self.hash_rate.height;
|
let hash_rate = &self.hash_rate.height;
|
||||||
for (sma, window) in [
|
for (sma, window) in [
|
||||||
(&mut self.hash_rate_sma_1w.height, &count_vecs.height_1w_ago),
|
(&mut self.hash_rate_sma_1w.height, &lookback.height_1w_ago),
|
||||||
(&mut self.hash_rate_sma_1m.height, &count_vecs.height_1m_ago),
|
(&mut self.hash_rate_sma_1m.height, &lookback.height_1m_ago),
|
||||||
(&mut self.hash_rate_sma_2m.height, &count_vecs.height_2m_ago),
|
(&mut self.hash_rate_sma_2m.height, &lookback.height_2m_ago),
|
||||||
(&mut self.hash_rate_sma_1y.height, &count_vecs.height_1y_ago),
|
(&mut self.hash_rate_sma_1y.height, &lookback.height_1y_ago),
|
||||||
] {
|
] {
|
||||||
sma.compute_rolling_average(starting_indexes.height, window, hash_rate, exit)?;
|
sma.compute_rolling_average(starting_indexes.height, window, hash_rate, exit)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ impl Vecs {
|
|||||||
&mut self,
|
&mut self,
|
||||||
indexer: &Indexer,
|
indexer: &Indexer,
|
||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
count_vecs: &blocks::CountVecs,
|
lookback: &blocks::LookbackVecs,
|
||||||
transactions_fees: &transactions::FeesVecs,
|
transactions_fees: &transactions::FeesVecs,
|
||||||
prices: &prices::Vecs,
|
prices: &prices::Vecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = lookback.window_starts();
|
||||||
|
|
||||||
self.coinbase.compute(
|
self.coinbase.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
@@ -163,7 +163,7 @@ impl Vecs {
|
|||||||
|
|
||||||
self.subsidy_sma_1y.cents.height.compute_rolling_average(
|
self.subsidy_sma_1y.cents.height.compute_rolling_average(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&count_vecs.height_1y_ago,
|
&lookback.height_1y_ago,
|
||||||
&self.subsidy.base.cents.height,
|
&self.subsidy.base.cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use super::Vecs;
|
|||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{
|
internal::{
|
||||||
FiatFromHeight, PercentFromHeight, PercentRollingWindows, ValueFromHeightCumulative,
|
AmountFromHeightCumulative, AmountFromHeightCumulativeSum, AmountFromHeightFull,
|
||||||
ValueFromHeightCumulativeSum, ValueFromHeightFull,
|
FiatFromHeight, PercentFromHeight, PercentRollingWindows,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -18,10 +18,12 @@ impl Vecs {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
coinbase: ValueFromHeightCumulativeSum::forced_import(db, "coinbase", version, indexes)?,
|
coinbase: AmountFromHeightCumulativeSum::forced_import(
|
||||||
subsidy: ValueFromHeightCumulative::forced_import(db, "subsidy", version, indexes)?,
|
db, "coinbase", version, indexes,
|
||||||
fees: ValueFromHeightFull::forced_import(db, "fees", version, indexes)?,
|
)?,
|
||||||
unclaimed_rewards: ValueFromHeightCumulativeSum::forced_import(
|
subsidy: AmountFromHeightCumulative::forced_import(db, "subsidy", version, indexes)?,
|
||||||
|
fees: AmountFromHeightFull::forced_import(db, "fees", version, indexes)?,
|
||||||
|
unclaimed_rewards: AmountFromHeightCumulativeSum::forced_import(
|
||||||
db,
|
db,
|
||||||
"unclaimed_rewards",
|
"unclaimed_rewards",
|
||||||
version,
|
version,
|
||||||
|
|||||||
@@ -3,16 +3,16 @@ use brk_types::{BasisPoints16, Cents};
|
|||||||
use vecdb::{Rw, StorageMode};
|
use vecdb::{Rw, StorageMode};
|
||||||
|
|
||||||
use crate::internal::{
|
use crate::internal::{
|
||||||
FiatFromHeight, PercentFromHeight, PercentRollingWindows, ValueFromHeightCumulative,
|
AmountFromHeightCumulative, AmountFromHeightCumulativeSum, AmountFromHeightFull,
|
||||||
ValueFromHeightCumulativeSum, ValueFromHeightFull,
|
FiatFromHeight, PercentFromHeight, PercentRollingWindows,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
pub coinbase: ValueFromHeightCumulativeSum<M>,
|
pub coinbase: AmountFromHeightCumulativeSum<M>,
|
||||||
pub subsidy: ValueFromHeightCumulative<M>,
|
pub subsidy: AmountFromHeightCumulative<M>,
|
||||||
pub fees: ValueFromHeightFull<M>,
|
pub fees: AmountFromHeightFull<M>,
|
||||||
pub unclaimed_rewards: ValueFromHeightCumulativeSum<M>,
|
pub unclaimed_rewards: AmountFromHeightCumulativeSum<M>,
|
||||||
pub fee_dominance: PercentFromHeight<BasisPoints16, M>,
|
pub fee_dominance: PercentFromHeight<BasisPoints16, M>,
|
||||||
pub fee_dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
|
pub fee_dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
|
||||||
pub subsidy_dominance: PercentFromHeight<BasisPoints16, M>,
|
pub subsidy_dominance: PercentFromHeight<BasisPoints16, M>,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ impl Vecs {
|
|||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
self.total_count
|
self.total_count
|
||||||
.compute(starting_indexes.height, &window_starts, exit, |full| {
|
.compute(starting_indexes.height, &window_starts, exit, |full| {
|
||||||
full.compute_with_skip(
|
full.compute_with_skip(
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use vecdb::{BinaryTransform, Database, Exit, ReadableVec, Rw, StorageMode, Versi
|
|||||||
use crate::{
|
use crate::{
|
||||||
blocks, indexes,
|
blocks, indexes,
|
||||||
internal::{
|
internal::{
|
||||||
MaskSats, PercentRollingWindows, RatioU32Bp16, RollingWindows,
|
AmountFromHeightCumulativeSum, MaskSats, PercentRollingWindows, RatioU32Bp16,
|
||||||
ValueFromHeightCumulativeSum,
|
RollingWindows,
|
||||||
},
|
},
|
||||||
mining, prices,
|
mining, prices,
|
||||||
};
|
};
|
||||||
@@ -25,7 +25,7 @@ pub struct Vecs<M: StorageMode = Rw> {
|
|||||||
|
|
||||||
#[traversable(wrap = "blocks_mined", rename = "sum")]
|
#[traversable(wrap = "blocks_mined", rename = "sum")]
|
||||||
pub blocks_mined_sum: RollingWindows<StoredU32, M>,
|
pub blocks_mined_sum: RollingWindows<StoredU32, M>,
|
||||||
pub rewards: ValueFromHeightCumulativeSum<M>,
|
pub rewards: AmountFromHeightCumulativeSum<M>,
|
||||||
pub dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
|
pub dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ impl Vecs {
|
|||||||
RollingWindows::forced_import(db, &suffix("blocks_mined"), version, indexes)?;
|
RollingWindows::forced_import(db, &suffix("blocks_mined"), version, indexes)?;
|
||||||
|
|
||||||
let rewards =
|
let rewards =
|
||||||
ValueFromHeightCumulativeSum::forced_import(db, &suffix("rewards"), version, indexes)?;
|
AmountFromHeightCumulativeSum::forced_import(db, &suffix("rewards"), version, indexes)?;
|
||||||
|
|
||||||
let dominance_rolling =
|
let dominance_rolling =
|
||||||
PercentRollingWindows::forced_import(db, &suffix("dominance"), version, indexes)?;
|
PercentRollingWindows::forced_import(db, &suffix("dominance"), version, indexes)?;
|
||||||
@@ -70,7 +70,7 @@ impl Vecs {
|
|||||||
self.base
|
self.base
|
||||||
.compute(starting_indexes, height_to_pool, blocks, exit)?;
|
.compute(starting_indexes, height_to_pool, blocks, exit)?;
|
||||||
|
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
|
|
||||||
self.blocks_mined_sum.compute_rolling_sum(
|
self.blocks_mined_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
@@ -79,17 +79,12 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
for (dom, (mined, total)) in self
|
for (dom, (mined, total)) in self.dominance_rolling.as_mut_array().into_iter().zip(
|
||||||
.dominance_rolling
|
self.blocks_mined_sum
|
||||||
.as_mut_array()
|
.as_array()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(
|
.zip(blocks.count.block_count.sum.as_array()),
|
||||||
self.blocks_mined_sum
|
) {
|
||||||
.as_array()
|
|
||||||
.into_iter()
|
|
||||||
.zip(blocks.count.block_count_sum.as_array()),
|
|
||||||
)
|
|
||||||
{
|
|
||||||
dom.compute_binary::<StoredU32, StoredU32, RatioU32Bp16>(
|
dom.compute_binary::<StoredU32, StoredU32, RatioU32Bp16>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&mined.height,
|
&mined.height,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ impl Vecs {
|
|||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.count
|
self.count
|
||||||
.compute(indexer, &blocks.count, starting_indexes, exit)?;
|
.compute(indexer, &blocks.lookback, starting_indexes, exit)?;
|
||||||
|
|
||||||
self.value
|
self.value
|
||||||
.compute(indexer, prices, starting_indexes, exit)?;
|
.compute(indexer, prices, starting_indexes, exit)?;
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ impl Vecs {
|
|||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
indexer: &Indexer,
|
indexer: &Indexer,
|
||||||
count_vecs: &blocks::CountVecs,
|
lookback: &blocks::LookbackVecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = lookback.window_starts();
|
||||||
|
|
||||||
self.p2a
|
self.p2a
|
||||||
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use brk_types::Version;
|
|||||||
use vecdb::Database;
|
use vecdb::Database;
|
||||||
|
|
||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{indexes, internal::ValueFromHeightCumulative};
|
use crate::{indexes, internal::AmountFromHeightCumulative};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
@@ -12,7 +12,7 @@ impl Vecs {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
opreturn: ValueFromHeightCumulative::forced_import(
|
opreturn: AmountFromHeightCumulative::forced_import(
|
||||||
db,
|
db,
|
||||||
"opreturn_value",
|
"opreturn_value",
|
||||||
version,
|
version,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use vecdb::{Rw, StorageMode};
|
use vecdb::{Rw, StorageMode};
|
||||||
|
|
||||||
use crate::internal::ValueFromHeightCumulative;
|
use crate::internal::AmountFromHeightCumulative;
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
pub opreturn: ValueFromHeightCumulative<M>,
|
pub opreturn: AmountFromHeightCumulative<M>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ impl Vecs {
|
|||||||
&mut self,
|
&mut self,
|
||||||
scripts: &scripts::Vecs,
|
scripts: &scripts::Vecs,
|
||||||
mining: &mining::Vecs,
|
mining: &mining::Vecs,
|
||||||
count_vecs: &blocks::CountVecs,
|
lookback: &blocks::LookbackVecs,
|
||||||
prices: &prices::Vecs,
|
prices: &prices::Vecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = lookback.window_starts();
|
||||||
|
|
||||||
// 1. Compute opreturn supply - copy per-block opreturn values from scripts
|
// 1. Compute opreturn supply - copy per-block opreturn values from scripts
|
||||||
self.opreturn.compute(
|
self.opreturn.compute(
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use brk_types::Version;
|
|||||||
use vecdb::Database;
|
use vecdb::Database;
|
||||||
|
|
||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{indexes, internal::ValueFromHeightCumulativeSum};
|
use crate::{indexes, internal::AmountFromHeightCumulativeSum};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
@@ -12,13 +12,13 @@ impl Vecs {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
opreturn: ValueFromHeightCumulativeSum::forced_import(
|
opreturn: AmountFromHeightCumulativeSum::forced_import(
|
||||||
db,
|
db,
|
||||||
"opreturn_supply",
|
"opreturn_supply",
|
||||||
version,
|
version,
|
||||||
indexes,
|
indexes,
|
||||||
)?,
|
)?,
|
||||||
unspendable: ValueFromHeightCumulativeSum::forced_import(
|
unspendable: AmountFromHeightCumulativeSum::forced_import(
|
||||||
db,
|
db,
|
||||||
"unspendable_supply",
|
"unspendable_supply",
|
||||||
version,
|
version,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use vecdb::{Rw, StorageMode};
|
use vecdb::{Rw, StorageMode};
|
||||||
|
|
||||||
use crate::internal::ValueFromHeightCumulativeSum;
|
use crate::internal::AmountFromHeightCumulativeSum;
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
pub opreturn: ValueFromHeightCumulativeSum<M>,
|
pub opreturn: AmountFromHeightCumulativeSum<M>,
|
||||||
pub unspendable: ValueFromHeightCumulativeSum<M>,
|
pub unspendable: AmountFromHeightCumulativeSum<M>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ impl Vecs {
|
|||||||
self.burned.compute(
|
self.burned.compute(
|
||||||
scripts,
|
scripts,
|
||||||
mining,
|
mining,
|
||||||
&blocks.count,
|
&blocks.lookback,
|
||||||
prices,
|
prices,
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
exit,
|
exit,
|
||||||
@@ -35,7 +35,7 @@ impl Vecs {
|
|||||||
.height
|
.height
|
||||||
.compute_rolling_ratio_change(
|
.compute_rolling_ratio_change(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1y_ago,
|
&blocks.lookback.height_1y_ago,
|
||||||
&circulating_supply.height,
|
&circulating_supply.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
@@ -45,7 +45,7 @@ impl Vecs {
|
|||||||
.compute(blocks, transactions, distribution, starting_indexes, exit)?;
|
.compute(blocks, transactions, distribution, starting_indexes, exit)?;
|
||||||
|
|
||||||
// 4. Compute market cap delta (change + rate across 4 windows)
|
// 4. Compute market cap delta (change + rate across 4 windows)
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
|
|
||||||
self.market_cap_delta.compute(
|
self.market_cap_delta.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use brk_types::{Cents, Dollars, Sats, Version};
|
|||||||
use crate::{
|
use crate::{
|
||||||
distribution, indexes,
|
distribution, indexes,
|
||||||
internal::{
|
internal::{
|
||||||
FiatRollingDelta, Identity, LazyFiatFromHeight, LazyValueFromHeight, PercentFromHeight,
|
FiatRollingDelta, Identity, LazyFiatFromHeight, LazyAmountFromHeight, PercentFromHeight,
|
||||||
RollingWindows, SatsToBitcoin, finalize_db, open_db,
|
RollingWindows, SatsToBitcoin, finalize_db, open_db,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -28,7 +28,7 @@ impl Vecs {
|
|||||||
let supply_metrics = &distribution.utxo_cohorts.all.metrics.supply;
|
let supply_metrics = &distribution.utxo_cohorts.all.metrics.supply;
|
||||||
|
|
||||||
// Circulating supply - lazy refs to distribution
|
// Circulating supply - lazy refs to distribution
|
||||||
let circulating = LazyValueFromHeight::from_block_source::<
|
let circulating = LazyAmountFromHeight::from_block_source::<
|
||||||
Identity<Sats>,
|
Identity<Sats>,
|
||||||
SatsToBitcoin,
|
SatsToBitcoin,
|
||||||
Identity<Cents>,
|
Identity<Cents>,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use vecdb::{Database, Rw, StorageMode};
|
|||||||
|
|
||||||
use super::{burned, velocity};
|
use super::{burned, velocity};
|
||||||
use crate::internal::{
|
use crate::internal::{
|
||||||
FiatRollingDelta, LazyFiatFromHeight, LazyValueFromHeight, PercentFromHeight, RollingWindows,
|
FiatRollingDelta, LazyFiatFromHeight, LazyAmountFromHeight, PercentFromHeight, RollingWindows,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
@@ -12,7 +12,7 @@ pub struct Vecs<M: StorageMode = Rw> {
|
|||||||
#[traversable(skip)]
|
#[traversable(skip)]
|
||||||
pub(crate) db: Database,
|
pub(crate) db: Database,
|
||||||
|
|
||||||
pub circulating: LazyValueFromHeight,
|
pub circulating: LazyAmountFromHeight,
|
||||||
pub burned: burned::Vecs<M>,
|
pub burned: burned::Vecs<M>,
|
||||||
pub inflation_rate: PercentFromHeight<BasisPointsSigned32, M>,
|
pub inflation_rate: PercentFromHeight<BasisPointsSigned32, M>,
|
||||||
pub velocity: velocity::Vecs<M>,
|
pub velocity: velocity::Vecs<M>,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ impl Vecs {
|
|||||||
// BTC velocity at height level
|
// BTC velocity at height level
|
||||||
self.btc.height.compute_rolling_ratio(
|
self.btc.height.compute_rolling_ratio(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1y_ago,
|
&blocks.lookback.height_1y_ago,
|
||||||
&transactions.volume.sent_sum.sats,
|
&transactions.volume.sent_sum.sats,
|
||||||
&circulating_supply.sats.height,
|
&circulating_supply.sats.height,
|
||||||
exit,
|
exit,
|
||||||
@@ -29,7 +29,7 @@ impl Vecs {
|
|||||||
// USD velocity at height level
|
// USD velocity at height level
|
||||||
self.usd.height.compute_rolling_ratio(
|
self.usd.height.compute_rolling_ratio(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1y_ago,
|
&blocks.lookback.height_1y_ago,
|
||||||
&transactions.volume.sent_sum.usd,
|
&transactions.volume.sent_sum.usd,
|
||||||
&circulating_supply.usd.height,
|
&circulating_supply.usd.height,
|
||||||
exit,
|
exit,
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ impl Vecs {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Count computes first
|
// Count computes first
|
||||||
self.count
|
self.count
|
||||||
.compute(indexer, &blocks.count, starting_indexes, exit)?;
|
.compute(indexer, &blocks.lookback, starting_indexes, exit)?;
|
||||||
|
|
||||||
// Versions depends on count
|
// Versions depends on count
|
||||||
self.versions
|
self.versions
|
||||||
.compute(indexer, &blocks.count, starting_indexes, exit)?;
|
.compute(indexer, &blocks.lookback, starting_indexes, exit)?;
|
||||||
|
|
||||||
// Size computes next (uses 6-block rolling window)
|
// Size computes next (uses 6-block rolling window)
|
||||||
self.size
|
self.size
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ impl Vecs {
|
|||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
indexer: &Indexer,
|
indexer: &Indexer,
|
||||||
count_vecs: &blocks::CountVecs,
|
lookback: &blocks::LookbackVecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = lookback.window_starts();
|
||||||
self.tx_count
|
self.tx_count
|
||||||
.compute(starting_indexes.height, &window_starts, exit, |height| {
|
.compute(starting_indexes.height, &window_starts, exit, |height| {
|
||||||
Ok(height.compute_count_from_indexes(
|
Ok(height.compute_count_from_indexes(
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ impl Vecs {
|
|||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
indexer: &Indexer,
|
indexer: &Indexer,
|
||||||
count_vecs: &blocks::CountVecs,
|
lookback: &blocks::LookbackVecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = lookback.window_starts();
|
||||||
|
|
||||||
let tx_vany = |tx_vany: &mut ComputedFromHeightCumulativeSum<StoredU64>,
|
let tx_vany = |tx_vany: &mut ComputedFromHeightCumulativeSum<StoredU64>,
|
||||||
txversion: TxVersion| {
|
txversion: TxVersion| {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ impl Vecs {
|
|||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.lookback.window_starts();
|
||||||
|
|
||||||
self.sent_sum.compute(
|
self.sent_sum.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
@@ -60,7 +60,7 @@ impl Vecs {
|
|||||||
// Annualized volume: rolling 1y sum of per-block sent volume
|
// Annualized volume: rolling 1y sum of per-block sent volume
|
||||||
self.annualized_volume.sats.height.compute_rolling_sum(
|
self.annualized_volume.sats.height.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1y_ago,
|
&blocks.lookback.height_1y_ago,
|
||||||
&self.sent_sum.sats,
|
&self.sent_sum.sats,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use vecdb::Database;
|
|||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{ComputedFromHeight, ValueFromHeight, ValueFromHeightRolling},
|
internal::{AmountFromHeight, AmountFromHeightRolling, ComputedFromHeight},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
@@ -16,14 +16,14 @@ impl Vecs {
|
|||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let v2 = Version::TWO;
|
let v2 = Version::TWO;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
sent_sum: ValueFromHeightRolling::forced_import(db, "sent_sum", version, indexes)?,
|
sent_sum: AmountFromHeightRolling::forced_import(db, "sent_sum", version, indexes)?,
|
||||||
received_sum: ValueFromHeightRolling::forced_import(
|
received_sum: AmountFromHeightRolling::forced_import(
|
||||||
db,
|
db,
|
||||||
"received_sum",
|
"received_sum",
|
||||||
version,
|
version,
|
||||||
indexes,
|
indexes,
|
||||||
)?,
|
)?,
|
||||||
annualized_volume: ValueFromHeight::forced_import(
|
annualized_volume: AmountFromHeight::forced_import(
|
||||||
db,
|
db,
|
||||||
"annualized_volume",
|
"annualized_volume",
|
||||||
version,
|
version,
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ use brk_traversable::Traversable;
|
|||||||
use brk_types::StoredF32;
|
use brk_types::StoredF32;
|
||||||
use vecdb::{Rw, StorageMode};
|
use vecdb::{Rw, StorageMode};
|
||||||
|
|
||||||
use crate::internal::{ComputedFromHeight, ValueFromHeight, ValueFromHeightRolling};
|
use crate::internal::{AmountFromHeight, AmountFromHeightRolling, ComputedFromHeight};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
pub sent_sum: ValueFromHeightRolling<M>,
|
pub sent_sum: AmountFromHeightRolling<M>,
|
||||||
pub received_sum: ValueFromHeightRolling<M>,
|
pub received_sum: AmountFromHeightRolling<M>,
|
||||||
pub annualized_volume: ValueFromHeight<M>,
|
pub annualized_volume: AmountFromHeight<M>,
|
||||||
pub tx_per_sec: ComputedFromHeight<StoredF32, M>,
|
pub tx_per_sec: ComputedFromHeight<StoredF32, M>,
|
||||||
pub outputs_per_sec: ComputedFromHeight<StoredF32, M>,
|
pub outputs_per_sec: ComputedFromHeight<StoredF32, M>,
|
||||||
pub inputs_per_sec: ComputedFromHeight<StoredF32, M>,
|
pub inputs_per_sec: ComputedFromHeight<StoredF32, M>,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ pub struct BlocksVecs<M: StorageMode = Rw> {
|
|||||||
/// Doesn't guarantee continuity due to possible reorgs and more generally the nature of mining
|
/// Doesn't guarantee continuity due to possible reorgs and more generally the nature of mining
|
||||||
#[traversable(wrap = "time")]
|
#[traversable(wrap = "time")]
|
||||||
pub timestamp: M::Stored<PcoVec<Height, Timestamp>>,
|
pub timestamp: M::Stored<PcoVec<Height, Timestamp>>,
|
||||||
|
#[traversable(wrap = "size")]
|
||||||
pub total_size: M::Stored<PcoVec<Height, StoredU64>>,
|
pub total_size: M::Stored<PcoVec<Height, StoredU64>>,
|
||||||
pub weight: M::Stored<PcoVec<Height, Weight>>,
|
pub weight: M::Stored<PcoVec<Height, Weight>>,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user