From 549e2da05bec186332843ac0aa491f23a6be7218 Mon Sep 17 00:00:00 2001 From: nym21 Date: Thu, 18 Dec 2025 16:08:32 +0100 Subject: [PATCH] computer: snapshot --- .../src/{chain.rs => chain/compute.rs} | 594 +----------------- crates/brk_computer/src/chain/import.rs | 475 ++++++++++++++ crates/brk_computer/src/chain/mod.rs | 132 ++++ .../src/{market.rs => market/compute.rs} | 427 +------------ crates/brk_computer/src/market/import.rs | 247 ++++++++ crates/brk_computer/src/market/mod.rs | 192 ++++++ 6 files changed, 1056 insertions(+), 1011 deletions(-) rename crates/brk_computer/src/{chain.rs => chain/compute.rs} (60%) create mode 100644 crates/brk_computer/src/chain/import.rs create mode 100644 crates/brk_computer/src/chain/mod.rs rename crates/brk_computer/src/{market.rs => market/compute.rs} (52%) create mode 100644 crates/brk_computer/src/market/import.rs create mode 100644 crates/brk_computer/src/market/mod.rs diff --git a/crates/brk_computer/src/chain.rs b/crates/brk_computer/src/chain/compute.rs similarity index 60% rename from crates/brk_computer/src/chain.rs rename to crates/brk_computer/src/chain/compute.rs index 1e0735ef8..9ebc299ba 100644 --- a/crates/brk_computer/src/chain.rs +++ b/crates/brk_computer/src/chain/compute.rs @@ -1,598 +1,16 @@ -use std::path::Path; - use brk_error::Result; use brk_indexer::Indexer; -use brk_traversable::Traversable; use brk_types::{ - Bitcoin, CheckedSub, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, FeeRate, HalvingEpoch, - Height, MonthIndex, ONE_DAY_IN_SEC_F64, QuarterIndex, Sats, SemesterIndex, StoredBool, - StoredF32, StoredF64, StoredU32, StoredU64, Timestamp, TxInIndex, TxIndex, TxOutIndex, - TxVersion, VSize, Version, WeekIndex, Weight, YearIndex, -}; -use vecdb::{ - Database, EagerVec, Exit, GenericStoredVec, ImportableVec, IterableCloneableVec, IterableVec, - LazyVecFrom1, LazyVecFrom2, PAGE_SIZE, PcoVec, TypedVecIterator, VecIndex, unlikely, + CheckedSub, FeeRate, HalvingEpoch, Height, ONE_DAY_IN_SEC_F64, Sats, StoredF32, StoredF64, + StoredU32, StoredU64, Timestamp, TxOutIndex, TxVersion, }; +use vecdb::{Exit, GenericStoredVec, IterableVec, TypedVecIterator, VecIndex, unlikely}; -use crate::{ - grouped::{ - ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromDateIndex, - ComputedVecsFromHeight, ComputedVecsFromTxindex, Source, VecBuilderOptions, - }, - utils::OptionExt, -}; +use crate::{grouped::ComputedVecsFromHeight, indexes, price, utils::OptionExt, Indexes}; -use super::{Indexes, indexes, price}; - -const TARGET_BLOCKS_PER_DAY_F64: f64 = 144.0; -const TARGET_BLOCKS_PER_DAY_F32: f32 = 144.0; -const TARGET_BLOCKS_PER_DAY: u64 = 144; -const TARGET_BLOCKS_PER_WEEK: u64 = 7 * TARGET_BLOCKS_PER_DAY; -const TARGET_BLOCKS_PER_MONTH: u64 = 30 * TARGET_BLOCKS_PER_DAY; -const TARGET_BLOCKS_PER_QUARTER: u64 = 3 * TARGET_BLOCKS_PER_MONTH; -const TARGET_BLOCKS_PER_SEMESTER: u64 = 2 * TARGET_BLOCKS_PER_QUARTER; -const TARGET_BLOCKS_PER_YEAR: u64 = 2 * TARGET_BLOCKS_PER_SEMESTER; -const TARGET_BLOCKS_PER_DECADE: u64 = 10 * TARGET_BLOCKS_PER_YEAR; -const ONE_TERA_HASH: f64 = 1_000_000_000_000.0; - -#[derive(Clone, Traversable)] -pub struct Vecs { - db: Database, - - pub dateindex_to_block_count_target: LazyVecFrom1, - pub weekindex_to_block_count_target: LazyVecFrom1, - pub monthindex_to_block_count_target: - LazyVecFrom1, - pub quarterindex_to_block_count_target: - LazyVecFrom1, - pub semesterindex_to_block_count_target: - LazyVecFrom1, - pub yearindex_to_block_count_target: LazyVecFrom1, - pub decadeindex_to_block_count_target: - LazyVecFrom1, - pub height_to_interval: EagerVec>, - pub height_to_24h_block_count: EagerVec>, - pub height_to_24h_coinbase_sum: EagerVec>, - pub height_to_24h_coinbase_usd_sum: EagerVec>, - pub height_to_vbytes: EagerVec>, - pub difficultyepoch_to_timestamp: EagerVec>, - pub halvingepoch_to_timestamp: EagerVec>, - pub timeindexes_to_timestamp: ComputedVecsFromDateIndex, - pub indexes_to_block_count: ComputedVecsFromHeight, - pub indexes_to_1w_block_count: ComputedVecsFromDateIndex, - pub indexes_to_1m_block_count: ComputedVecsFromDateIndex, - pub indexes_to_1y_block_count: ComputedVecsFromDateIndex, - pub indexes_to_block_interval: ComputedVecsFromHeight, - pub indexes_to_block_size: ComputedVecsFromHeight, - pub indexes_to_block_vbytes: ComputedVecsFromHeight, - pub indexes_to_block_weight: ComputedVecsFromHeight, - pub indexes_to_difficulty: ComputedVecsFromHeight, - pub indexes_to_difficultyepoch: ComputedVecsFromDateIndex, - pub indexes_to_halvingepoch: ComputedVecsFromDateIndex, - pub indexes_to_coinbase: ComputedValueVecsFromHeight, - pub indexes_to_emptyoutput_count: ComputedVecsFromHeight, - pub indexes_to_fee: ComputedValueVecsFromTxindex, - pub indexes_to_fee_rate: ComputedVecsFromTxindex, - /// Value == 0 when Coinbase - pub txindex_to_input_value: EagerVec>, - pub indexes_to_sent_sum: ComputedValueVecsFromHeight, - // pub indexes_to_input_value: ComputedVecsFromTxindex, - pub indexes_to_opreturn_count: ComputedVecsFromHeight, - pub txindex_to_output_value: EagerVec>, - // pub indexes_to_output_value: ComputedVecsFromTxindex, - pub indexes_to_p2a_count: ComputedVecsFromHeight, - pub indexes_to_p2ms_count: ComputedVecsFromHeight, - pub indexes_to_p2pk33_count: ComputedVecsFromHeight, - pub indexes_to_p2pk65_count: ComputedVecsFromHeight, - pub indexes_to_p2pkh_count: ComputedVecsFromHeight, - pub indexes_to_p2sh_count: ComputedVecsFromHeight, - pub indexes_to_p2tr_count: ComputedVecsFromHeight, - pub indexes_to_p2wpkh_count: ComputedVecsFromHeight, - pub indexes_to_p2wsh_count: ComputedVecsFromHeight, - pub indexes_to_subsidy: ComputedValueVecsFromHeight, - pub indexes_to_unclaimed_rewards: ComputedValueVecsFromHeight, - pub indexes_to_tx_count: ComputedVecsFromHeight, - pub indexes_to_tx_v1: ComputedVecsFromHeight, - pub indexes_to_tx_v2: ComputedVecsFromHeight, - pub indexes_to_tx_v3: ComputedVecsFromHeight, - pub indexes_to_tx_vsize: ComputedVecsFromTxindex, - pub indexes_to_tx_weight: ComputedVecsFromTxindex, - pub indexes_to_unknownoutput_count: ComputedVecsFromHeight, - pub txinindex_to_value: EagerVec>, - pub indexes_to_input_count: ComputedVecsFromTxindex, - pub txindex_to_is_coinbase: LazyVecFrom2, - pub indexes_to_output_count: ComputedVecsFromTxindex, - pub txindex_to_vsize: LazyVecFrom1, - pub txindex_to_weight: LazyVecFrom2, - pub txindex_to_fee: EagerVec>, - pub txindex_to_fee_rate: EagerVec>, - pub indexes_to_exact_utxo_count: ComputedVecsFromHeight, - pub dateindex_to_fee_dominance: EagerVec>, - pub dateindex_to_subsidy_dominance: EagerVec>, - pub indexes_to_subsidy_usd_1y_sma: Option>, - pub indexes_to_puell_multiple: Option>, - pub indexes_to_hash_rate: ComputedVecsFromHeight, - pub indexes_to_hash_rate_1w_sma: ComputedVecsFromDateIndex, - pub indexes_to_hash_rate_1m_sma: ComputedVecsFromDateIndex, - pub indexes_to_hash_rate_2m_sma: ComputedVecsFromDateIndex, - pub indexes_to_hash_rate_1y_sma: ComputedVecsFromDateIndex, - pub indexes_to_hash_price_ths: ComputedVecsFromHeight, - pub indexes_to_hash_price_ths_min: ComputedVecsFromHeight, - pub indexes_to_hash_price_phs: ComputedVecsFromHeight, - pub indexes_to_hash_price_phs_min: ComputedVecsFromHeight, - pub indexes_to_hash_price_rebound: ComputedVecsFromHeight, - pub indexes_to_hash_value_ths: ComputedVecsFromHeight, - pub indexes_to_hash_value_ths_min: ComputedVecsFromHeight, - pub indexes_to_hash_value_phs: ComputedVecsFromHeight, - pub indexes_to_hash_value_phs_min: ComputedVecsFromHeight, - pub indexes_to_hash_value_rebound: ComputedVecsFromHeight, - pub indexes_to_difficulty_as_hash: ComputedVecsFromHeight, - pub indexes_to_difficulty_adjustment: ComputedVecsFromHeight, - pub indexes_to_blocks_before_next_difficulty_adjustment: ComputedVecsFromHeight, - pub indexes_to_days_before_next_difficulty_adjustment: ComputedVecsFromHeight, - pub indexes_to_blocks_before_next_halving: ComputedVecsFromHeight, - pub indexes_to_days_before_next_halving: ComputedVecsFromHeight, - pub indexes_to_inflation_rate: ComputedVecsFromDateIndex, - pub indexes_to_annualized_volume: ComputedVecsFromDateIndex, - pub indexes_to_annualized_volume_btc: ComputedVecsFromDateIndex, - pub indexes_to_annualized_volume_usd: ComputedVecsFromDateIndex, - pub indexes_to_tx_btc_velocity: ComputedVecsFromDateIndex, - pub indexes_to_tx_usd_velocity: ComputedVecsFromDateIndex, - pub indexes_to_tx_per_sec: ComputedVecsFromDateIndex, - pub indexes_to_outputs_per_sec: ComputedVecsFromDateIndex, - pub indexes_to_inputs_per_sec: ComputedVecsFromDateIndex, -} +use super::{Vecs, ONE_TERA_HASH, TARGET_BLOCKS_PER_DAY_F32, TARGET_BLOCKS_PER_DAY_F64}; impl Vecs { - pub fn forced_import( - parent_path: &Path, - parent_version: Version, - indexer: &Indexer, - indexes: &indexes::Vecs, - price: Option<&price::Vecs>, - ) -> Result { - let db = Database::open(&parent_path.join("chain"))?; - db.set_min_len(PAGE_SIZE * 50_000_000)?; - - let version = parent_version + Version::ZERO; - - let compute_dollars = price.is_some(); - let v0 = Version::ZERO; - let v2 = Version::TWO; - let v4 = Version::new(4); - let v5 = Version::new(5); - - // Helper macros for common patterns - macro_rules! eager { - ($name:expr) => { - EagerVec::forced_import(&db, $name, version + v0)? - }; - ($name:expr, $v:expr) => { - EagerVec::forced_import(&db, $name, version + $v)? - }; - } - macro_rules! computed_h { - ($name:expr, $source:expr, $opts:expr) => { - ComputedVecsFromHeight::forced_import( - &db, - $name, - $source, - version + v0, - indexes, - $opts, - )? - }; - ($name:expr, $source:expr, $v:expr, $opts:expr) => { - ComputedVecsFromHeight::forced_import( - &db, - $name, - $source, - version + $v, - indexes, - $opts, - )? - }; - } - macro_rules! computed_di { - ($name:expr, $opts:expr) => { - ComputedVecsFromDateIndex::forced_import( - &db, - $name, - Source::Compute, - version + v0, - indexes, - $opts, - )? - }; - ($name:expr, $v:expr, $opts:expr) => { - ComputedVecsFromDateIndex::forced_import( - &db, - $name, - Source::Compute, - version + $v, - indexes, - $opts, - )? - }; - } - macro_rules! computed_tx { - ($name:expr, $source:expr, $opts:expr) => { - ComputedVecsFromTxindex::forced_import( - &db, - $name, - $source, - version + v0, - indexes, - $opts, - )? - }; - } - let last = || VecBuilderOptions::default().add_last(); - let sum = || VecBuilderOptions::default().add_sum(); - let sum_cum = || VecBuilderOptions::default().add_sum().add_cumulative(); - let stats = || { - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - }; - let full_stats = || { - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative() - }; - - let txinindex_to_value: EagerVec> = eager!("value"); - - let txindex_to_weight = LazyVecFrom2::init( - "weight", - version + Version::ZERO, - indexer.vecs.tx.txindex_to_base_size.boxed_clone(), - indexer.vecs.tx.txindex_to_total_size.boxed_clone(), - |index: TxIndex, txindex_to_base_size_iter, txindex_to_total_size_iter| { - let index = index.to_usize(); - txindex_to_base_size_iter.get_at(index).map(|base_size| { - let total_size = txindex_to_total_size_iter.get_at_unwrap(index); - - // This is the exact definition of a weight unit, as defined by BIP-141 (quote above). - let wu = usize::from(base_size) * 3 + usize::from(total_size); - - Weight::from(bitcoin::Weight::from_wu_usize(wu)) - }) - }, - ); - - let txindex_to_vsize = LazyVecFrom1::init( - "vsize", - version + Version::ZERO, - txindex_to_weight.boxed_clone(), - |index: TxIndex, iter| iter.get(index).map(VSize::from), - ); - - let txindex_to_is_coinbase = LazyVecFrom2::init( - "is_coinbase", - version + Version::ZERO, - indexer.vecs.tx.txindex_to_height.boxed_clone(), - indexer.vecs.tx.height_to_first_txindex.boxed_clone(), - |index: TxIndex, txindex_to_height_iter, height_to_first_txindex_iter| { - txindex_to_height_iter.get(index).map(|height| { - let txindex = height_to_first_txindex_iter.get_unwrap(height); - StoredBool::from(index == txindex) - }) - }, - ); - - let txindex_to_input_value = eager!("input_value"); - let txindex_to_output_value = eager!("output_value"); - let txindex_to_fee = eager!("fee"); - let txindex_to_fee_rate = eager!("fee_rate"); - - let dateindex_to_block_count_target = LazyVecFrom1::init( - "block_count_target", - version + Version::ZERO, - indexes.dateindex_to_dateindex.boxed_clone(), - |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DAY)), - ); - let weekindex_to_block_count_target = LazyVecFrom1::init( - "block_count_target", - version + Version::ZERO, - indexes.weekindex_to_weekindex.boxed_clone(), - |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_WEEK)), - ); - let monthindex_to_block_count_target = LazyVecFrom1::init( - "block_count_target", - version + Version::ZERO, - indexes.monthindex_to_monthindex.boxed_clone(), - |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_MONTH)), - ); - let quarterindex_to_block_count_target = LazyVecFrom1::init( - "block_count_target", - version + Version::ZERO, - indexes.quarterindex_to_quarterindex.boxed_clone(), - |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_QUARTER)), - ); - let semesterindex_to_block_count_target = LazyVecFrom1::init( - "block_count_target", - version + Version::ZERO, - indexes.semesterindex_to_semesterindex.boxed_clone(), - |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_SEMESTER)), - ); - let yearindex_to_block_count_target = LazyVecFrom1::init( - "block_count_target", - version + Version::ZERO, - indexes.yearindex_to_yearindex.boxed_clone(), - |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_YEAR)), - ); - let decadeindex_to_block_count_target = LazyVecFrom1::init( - "block_count_target", - version + Version::ZERO, - indexes.decadeindex_to_decadeindex.boxed_clone(), - |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DECADE)), - ); - - let this = Self { - dateindex_to_block_count_target, - weekindex_to_block_count_target, - monthindex_to_block_count_target, - quarterindex_to_block_count_target, - semesterindex_to_block_count_target, - yearindex_to_block_count_target, - decadeindex_to_block_count_target, - height_to_interval: eager!("interval"), - timeindexes_to_timestamp: computed_di!( - "timestamp", - VecBuilderOptions::default().add_first() - ), - indexes_to_block_interval: computed_h!("block_interval", Source::None, stats()), - indexes_to_block_count: computed_h!("block_count", Source::Compute, sum_cum()), - indexes_to_1w_block_count: computed_di!("1w_block_count", last()), - indexes_to_1m_block_count: computed_di!("1m_block_count", last()), - indexes_to_1y_block_count: computed_di!("1y_block_count", last()), - indexes_to_block_weight: computed_h!("block_weight", Source::None, full_stats()), - indexes_to_block_size: computed_h!("block_size", Source::None, full_stats()), - height_to_vbytes: eager!("vbytes"), - height_to_24h_block_count: eager!("24h_block_count"), - height_to_24h_coinbase_sum: eager!("24h_coinbase_sum"), - height_to_24h_coinbase_usd_sum: eager!("24h_coinbase_usd_sum"), - indexes_to_block_vbytes: computed_h!("block_vbytes", Source::None, full_stats()), - difficultyepoch_to_timestamp: eager!("timestamp"), - halvingepoch_to_timestamp: eager!("timestamp"), - - dateindex_to_fee_dominance: eager!("fee_dominance"), - dateindex_to_subsidy_dominance: eager!("subsidy_dominance"), - indexes_to_difficulty: computed_h!("difficulty", Source::None, last()), - indexes_to_difficultyepoch: computed_di!("difficultyepoch", last()), - indexes_to_halvingepoch: computed_di!("halvingepoch", last()), - indexes_to_tx_count: computed_h!("tx_count", Source::Compute, full_stats()), - indexes_to_input_count: computed_tx!("input_count", Source::None, full_stats()), - indexes_to_output_count: computed_tx!("output_count", Source::None, full_stats()), - indexes_to_tx_v1: computed_h!("tx_v1", Source::Compute, sum_cum()), - indexes_to_tx_v2: computed_h!("tx_v2", Source::Compute, sum_cum()), - indexes_to_tx_v3: computed_h!("tx_v3", Source::Compute, sum_cum()), - indexes_to_sent_sum: ComputedValueVecsFromHeight::forced_import( - &db, - "sent_sum", - Source::Compute, - version + Version::ZERO, - VecBuilderOptions::default().add_sum(), - compute_dollars, - indexes, - )?, - indexes_to_fee: ComputedValueVecsFromTxindex::forced_import( - &db, - "fee", - indexer, - indexes, - Source::Vec(txindex_to_fee.boxed_clone()), - version + Version::ZERO, - price, - VecBuilderOptions::default() - .add_sum() - .add_cumulative() - .add_percentiles() - .add_minmax() - .add_average(), - )?, - indexes_to_fee_rate: computed_tx!("fee_rate", Source::None, stats()), - indexes_to_tx_vsize: computed_tx!("tx_vsize", Source::None, stats()), - indexes_to_tx_weight: computed_tx!("tx_weight", Source::None, stats()), - indexes_to_subsidy: ComputedValueVecsFromHeight::forced_import( - &db, - "subsidy", - Source::Compute, - version + Version::ZERO, - VecBuilderOptions::default() - .add_percentiles() - .add_sum() - .add_cumulative() - .add_minmax() - .add_average(), - compute_dollars, - indexes, - )?, - indexes_to_coinbase: ComputedValueVecsFromHeight::forced_import( - &db, - "coinbase", - Source::Compute, - version + Version::ZERO, - VecBuilderOptions::default() - .add_sum() - .add_cumulative() - .add_percentiles() - .add_minmax() - .add_average(), - compute_dollars, - indexes, - )?, - indexes_to_unclaimed_rewards: ComputedValueVecsFromHeight::forced_import( - &db, - "unclaimed_rewards", - Source::Compute, - version + Version::ZERO, - VecBuilderOptions::default().add_sum().add_cumulative(), - compute_dollars, - indexes, - )?, - indexes_to_p2a_count: computed_h!("p2a_count", Source::Compute, full_stats()), - indexes_to_p2ms_count: computed_h!("p2ms_count", Source::Compute, full_stats()), - indexes_to_p2pk33_count: computed_h!("p2pk33_count", Source::Compute, full_stats()), - indexes_to_p2pk65_count: computed_h!("p2pk65_count", Source::Compute, full_stats()), - indexes_to_p2pkh_count: computed_h!("p2pkh_count", Source::Compute, full_stats()), - indexes_to_p2sh_count: computed_h!("p2sh_count", Source::Compute, full_stats()), - indexes_to_p2tr_count: computed_h!("p2tr_count", Source::Compute, full_stats()), - indexes_to_p2wpkh_count: computed_h!("p2wpkh_count", Source::Compute, full_stats()), - indexes_to_p2wsh_count: computed_h!("p2wsh_count", Source::Compute, full_stats()), - indexes_to_opreturn_count: computed_h!("opreturn_count", Source::Compute, full_stats()), - indexes_to_unknownoutput_count: computed_h!( - "unknownoutput_count", - Source::Compute, - full_stats() - ), - indexes_to_emptyoutput_count: computed_h!( - "emptyoutput_count", - Source::Compute, - full_stats() - ), - indexes_to_exact_utxo_count: computed_h!("exact_utxo_count", Source::Compute, last()), - indexes_to_subsidy_usd_1y_sma: compute_dollars - .then(|| { - ComputedVecsFromDateIndex::forced_import( - &db, - "subsidy_usd_1y_sma", - Source::Compute, - version + v0, - indexes, - last(), - ) - }) - .transpose()?, - indexes_to_puell_multiple: compute_dollars - .then(|| { - ComputedVecsFromDateIndex::forced_import( - &db, - "puell_multiple", - Source::Compute, - version + v0, - indexes, - last(), - ) - }) - .transpose()?, - indexes_to_hash_rate: computed_h!("hash_rate", Source::Compute, v5, last()), - indexes_to_hash_rate_1w_sma: computed_di!("hash_rate_1w_sma", last()), - indexes_to_hash_rate_1m_sma: computed_di!("hash_rate_1m_sma", last()), - indexes_to_hash_rate_2m_sma: computed_di!("hash_rate_2m_sma", last()), - indexes_to_hash_rate_1y_sma: computed_di!("hash_rate_1y_sma", last()), - indexes_to_difficulty_as_hash: computed_h!( - "difficulty_as_hash", - Source::Compute, - last() - ), - indexes_to_difficulty_adjustment: computed_h!( - "difficulty_adjustment", - Source::Compute, - sum() - ), - indexes_to_blocks_before_next_difficulty_adjustment: computed_h!( - "blocks_before_next_difficulty_adjustment", - Source::Compute, - v2, - last() - ), - indexes_to_days_before_next_difficulty_adjustment: computed_h!( - "days_before_next_difficulty_adjustment", - Source::Compute, - v2, - last() - ), - indexes_to_blocks_before_next_halving: computed_h!( - "blocks_before_next_halving", - Source::Compute, - v2, - last() - ), - indexes_to_days_before_next_halving: computed_h!( - "days_before_next_halving", - Source::Compute, - v2, - last() - ), - indexes_to_hash_price_ths: computed_h!("hash_price_ths", Source::Compute, v4, last()), - indexes_to_hash_price_phs: computed_h!("hash_price_phs", Source::Compute, v4, last()), - indexes_to_hash_value_ths: computed_h!("hash_value_ths", Source::Compute, v4, last()), - indexes_to_hash_value_phs: computed_h!("hash_value_phs", Source::Compute, v4, last()), - indexes_to_hash_price_ths_min: computed_h!( - "hash_price_ths_min", - Source::Compute, - v4, - last() - ), - indexes_to_hash_price_phs_min: computed_h!( - "hash_price_phs_min", - Source::Compute, - v4, - last() - ), - indexes_to_hash_price_rebound: computed_h!( - "hash_price_rebound", - Source::Compute, - v4, - last() - ), - indexes_to_hash_value_ths_min: computed_h!( - "hash_value_ths_min", - Source::Compute, - v4, - last() - ), - indexes_to_hash_value_phs_min: computed_h!( - "hash_value_phs_min", - Source::Compute, - v4, - last() - ), - indexes_to_hash_value_rebound: computed_h!( - "hash_value_rebound", - Source::Compute, - v4, - last() - ), - indexes_to_inflation_rate: computed_di!("inflation_rate", last()), - indexes_to_annualized_volume: computed_di!("annualized_volume", last()), - indexes_to_annualized_volume_btc: computed_di!("annualized_volume_btc", last()), - indexes_to_annualized_volume_usd: computed_di!("annualized_volume_usd", last()), - indexes_to_tx_btc_velocity: computed_di!("tx_btc_velocity", last()), - indexes_to_tx_usd_velocity: computed_di!("tx_usd_velocity", last()), - indexes_to_tx_per_sec: computed_di!("tx_per_sec", v2, last()), - indexes_to_outputs_per_sec: computed_di!("outputs_per_sec", v2, last()), - indexes_to_inputs_per_sec: computed_di!("inputs_per_sec", v2, last()), - - txindex_to_is_coinbase, - txinindex_to_value, - txindex_to_input_value, - txindex_to_output_value, - txindex_to_fee, - txindex_to_fee_rate, - txindex_to_vsize, - txindex_to_weight, - - db, - }; - - this.db.retain_regions( - this.iter_any_exportable() - .flat_map(|v| v.region_names()) - .collect(), - )?; - - this.db.compact()?; - - Ok(this) - } - pub fn compute( &mut self, indexer: &Indexer, @@ -1034,7 +452,7 @@ impl Vecs { let sum = range .map(Height::from) .map(|h| height_to_coinbase_iter.get_unwrap(h)) - .sum::(); + .sum::(); (h, sum) }, exit, diff --git a/crates/brk_computer/src/chain/import.rs b/crates/brk_computer/src/chain/import.rs new file mode 100644 index 000000000..0e20cc8b8 --- /dev/null +++ b/crates/brk_computer/src/chain/import.rs @@ -0,0 +1,475 @@ +use std::path::Path; + +use brk_error::Result; +use brk_indexer::Indexer; +use brk_traversable::Traversable; +use brk_types::{StoredBool, StoredU64, TxIndex, Version, Weight}; +use vecdb::{ + Database, EagerVec, ImportableVec, IterableCloneableVec, LazyVecFrom1, LazyVecFrom2, PAGE_SIZE, + VecIndex, +}; + +use crate::{ + grouped::{ + ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromDateIndex, + ComputedVecsFromHeight, ComputedVecsFromTxindex, Source, VecBuilderOptions, + }, + indexes, price, +}; + +use super::{ + Vecs, TARGET_BLOCKS_PER_DAY, TARGET_BLOCKS_PER_DECADE, TARGET_BLOCKS_PER_MONTH, + TARGET_BLOCKS_PER_QUARTER, TARGET_BLOCKS_PER_SEMESTER, TARGET_BLOCKS_PER_WEEK, + TARGET_BLOCKS_PER_YEAR, +}; + +impl Vecs { + pub fn forced_import( + parent_path: &Path, + parent_version: Version, + indexer: &Indexer, + indexes: &indexes::Vecs, + price: Option<&price::Vecs>, + ) -> Result { + let db = Database::open(&parent_path.join("chain"))?; + db.set_min_len(PAGE_SIZE * 50_000_000)?; + + let version = parent_version + Version::ZERO; + + let compute_dollars = price.is_some(); + let v0 = Version::ZERO; + let v2 = Version::TWO; + let v4 = Version::new(4); + let v5 = Version::new(5); + + // Helper macros for common patterns + macro_rules! eager { + ($name:expr) => { + EagerVec::forced_import(&db, $name, version + v0)? + }; + ($name:expr, $v:expr) => { + EagerVec::forced_import(&db, $name, version + $v)? + }; + } + macro_rules! computed_h { + ($name:expr, $source:expr, $opts:expr) => { + ComputedVecsFromHeight::forced_import( + &db, + $name, + $source, + version + v0, + indexes, + $opts, + )? + }; + ($name:expr, $source:expr, $v:expr, $opts:expr) => { + ComputedVecsFromHeight::forced_import( + &db, + $name, + $source, + version + $v, + indexes, + $opts, + )? + }; + } + macro_rules! computed_di { + ($name:expr, $opts:expr) => { + ComputedVecsFromDateIndex::forced_import( + &db, + $name, + Source::Compute, + version + v0, + indexes, + $opts, + )? + }; + ($name:expr, $v:expr, $opts:expr) => { + ComputedVecsFromDateIndex::forced_import( + &db, + $name, + Source::Compute, + version + $v, + indexes, + $opts, + )? + }; + } + macro_rules! computed_tx { + ($name:expr, $source:expr, $opts:expr) => { + ComputedVecsFromTxindex::forced_import( + &db, + $name, + $source, + version + v0, + indexes, + $opts, + )? + }; + } + let last = || VecBuilderOptions::default().add_last(); + let sum = || VecBuilderOptions::default().add_sum(); + let sum_cum = || VecBuilderOptions::default().add_sum().add_cumulative(); + let stats = || { + VecBuilderOptions::default() + .add_average() + .add_minmax() + .add_percentiles() + }; + let full_stats = || { + VecBuilderOptions::default() + .add_average() + .add_minmax() + .add_percentiles() + .add_sum() + .add_cumulative() + }; + + let txinindex_to_value = eager!("value"); + + let txindex_to_weight = LazyVecFrom2::init( + "weight", + version + Version::ZERO, + indexer.vecs.tx.txindex_to_base_size.boxed_clone(), + indexer.vecs.tx.txindex_to_total_size.boxed_clone(), + |index: TxIndex, txindex_to_base_size_iter, txindex_to_total_size_iter| { + let index = index.to_usize(); + txindex_to_base_size_iter.get_at(index).map(|base_size| { + let total_size = txindex_to_total_size_iter.get_at_unwrap(index); + + // This is the exact definition of a weight unit, as defined by BIP-141 (quote above). + let wu = usize::from(base_size) * 3 + usize::from(total_size); + + Weight::from(bitcoin::Weight::from_wu_usize(wu)) + }) + }, + ); + + let txindex_to_vsize = LazyVecFrom1::init( + "vsize", + version + Version::ZERO, + txindex_to_weight.boxed_clone(), + |index: TxIndex, iter| iter.get(index).map(brk_types::VSize::from), + ); + + let txindex_to_is_coinbase = LazyVecFrom2::init( + "is_coinbase", + version + Version::ZERO, + indexer.vecs.tx.txindex_to_height.boxed_clone(), + indexer.vecs.tx.height_to_first_txindex.boxed_clone(), + |index: TxIndex, txindex_to_height_iter, height_to_first_txindex_iter| { + txindex_to_height_iter.get(index).map(|height| { + let txindex = height_to_first_txindex_iter.get_unwrap(height); + StoredBool::from(index == txindex) + }) + }, + ); + + let txindex_to_input_value = eager!("input_value"); + let txindex_to_output_value = eager!("output_value"); + let txindex_to_fee = eager!("fee"); + let txindex_to_fee_rate = eager!("fee_rate"); + + let dateindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + Version::ZERO, + indexes.dateindex_to_dateindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DAY)), + ); + let weekindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + Version::ZERO, + indexes.weekindex_to_weekindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_WEEK)), + ); + let monthindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + Version::ZERO, + indexes.monthindex_to_monthindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_MONTH)), + ); + let quarterindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + Version::ZERO, + indexes.quarterindex_to_quarterindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_QUARTER)), + ); + let semesterindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + Version::ZERO, + indexes.semesterindex_to_semesterindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_SEMESTER)), + ); + let yearindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + Version::ZERO, + indexes.yearindex_to_yearindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_YEAR)), + ); + let decadeindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + Version::ZERO, + indexes.decadeindex_to_decadeindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DECADE)), + ); + + let this = Self { + dateindex_to_block_count_target, + weekindex_to_block_count_target, + monthindex_to_block_count_target, + quarterindex_to_block_count_target, + semesterindex_to_block_count_target, + yearindex_to_block_count_target, + decadeindex_to_block_count_target, + height_to_interval: eager!("interval"), + timeindexes_to_timestamp: computed_di!( + "timestamp", + VecBuilderOptions::default().add_first() + ), + indexes_to_block_interval: computed_h!("block_interval", Source::None, stats()), + indexes_to_block_count: computed_h!("block_count", Source::Compute, sum_cum()), + indexes_to_1w_block_count: computed_di!("1w_block_count", last()), + indexes_to_1m_block_count: computed_di!("1m_block_count", last()), + indexes_to_1y_block_count: computed_di!("1y_block_count", last()), + indexes_to_block_weight: computed_h!("block_weight", Source::None, full_stats()), + indexes_to_block_size: computed_h!("block_size", Source::None, full_stats()), + height_to_vbytes: eager!("vbytes"), + height_to_24h_block_count: eager!("24h_block_count"), + height_to_24h_coinbase_sum: eager!("24h_coinbase_sum"), + height_to_24h_coinbase_usd_sum: eager!("24h_coinbase_usd_sum"), + indexes_to_block_vbytes: computed_h!("block_vbytes", Source::None, full_stats()), + difficultyepoch_to_timestamp: eager!("timestamp"), + halvingepoch_to_timestamp: eager!("timestamp"), + + dateindex_to_fee_dominance: eager!("fee_dominance"), + dateindex_to_subsidy_dominance: eager!("subsidy_dominance"), + indexes_to_difficulty: computed_h!("difficulty", Source::None, last()), + indexes_to_difficultyepoch: computed_di!("difficultyepoch", last()), + indexes_to_halvingepoch: computed_di!("halvingepoch", last()), + indexes_to_tx_count: computed_h!("tx_count", Source::Compute, full_stats()), + indexes_to_input_count: computed_tx!("input_count", Source::None, full_stats()), + indexes_to_output_count: computed_tx!("output_count", Source::None, full_stats()), + indexes_to_tx_v1: computed_h!("tx_v1", Source::Compute, sum_cum()), + indexes_to_tx_v2: computed_h!("tx_v2", Source::Compute, sum_cum()), + indexes_to_tx_v3: computed_h!("tx_v3", Source::Compute, sum_cum()), + indexes_to_sent_sum: ComputedValueVecsFromHeight::forced_import( + &db, + "sent_sum", + Source::Compute, + version + Version::ZERO, + VecBuilderOptions::default().add_sum(), + compute_dollars, + indexes, + )?, + indexes_to_fee: ComputedValueVecsFromTxindex::forced_import( + &db, + "fee", + indexer, + indexes, + Source::Vec(txindex_to_fee.boxed_clone()), + version + Version::ZERO, + price, + VecBuilderOptions::default() + .add_sum() + .add_cumulative() + .add_percentiles() + .add_minmax() + .add_average(), + )?, + indexes_to_fee_rate: computed_tx!("fee_rate", Source::None, stats()), + indexes_to_tx_vsize: computed_tx!("tx_vsize", Source::None, stats()), + indexes_to_tx_weight: computed_tx!("tx_weight", Source::None, stats()), + indexes_to_subsidy: ComputedValueVecsFromHeight::forced_import( + &db, + "subsidy", + Source::Compute, + version + Version::ZERO, + VecBuilderOptions::default() + .add_percentiles() + .add_sum() + .add_cumulative() + .add_minmax() + .add_average(), + compute_dollars, + indexes, + )?, + indexes_to_coinbase: ComputedValueVecsFromHeight::forced_import( + &db, + "coinbase", + Source::Compute, + version + Version::ZERO, + VecBuilderOptions::default() + .add_sum() + .add_cumulative() + .add_percentiles() + .add_minmax() + .add_average(), + compute_dollars, + indexes, + )?, + indexes_to_unclaimed_rewards: ComputedValueVecsFromHeight::forced_import( + &db, + "unclaimed_rewards", + Source::Compute, + version + Version::ZERO, + VecBuilderOptions::default().add_sum().add_cumulative(), + compute_dollars, + indexes, + )?, + indexes_to_p2a_count: computed_h!("p2a_count", Source::Compute, full_stats()), + indexes_to_p2ms_count: computed_h!("p2ms_count", Source::Compute, full_stats()), + indexes_to_p2pk33_count: computed_h!("p2pk33_count", Source::Compute, full_stats()), + indexes_to_p2pk65_count: computed_h!("p2pk65_count", Source::Compute, full_stats()), + indexes_to_p2pkh_count: computed_h!("p2pkh_count", Source::Compute, full_stats()), + indexes_to_p2sh_count: computed_h!("p2sh_count", Source::Compute, full_stats()), + indexes_to_p2tr_count: computed_h!("p2tr_count", Source::Compute, full_stats()), + indexes_to_p2wpkh_count: computed_h!("p2wpkh_count", Source::Compute, full_stats()), + indexes_to_p2wsh_count: computed_h!("p2wsh_count", Source::Compute, full_stats()), + indexes_to_opreturn_count: computed_h!("opreturn_count", Source::Compute, full_stats()), + indexes_to_unknownoutput_count: computed_h!( + "unknownoutput_count", + Source::Compute, + full_stats() + ), + indexes_to_emptyoutput_count: computed_h!( + "emptyoutput_count", + Source::Compute, + full_stats() + ), + indexes_to_exact_utxo_count: computed_h!("exact_utxo_count", Source::Compute, last()), + indexes_to_subsidy_usd_1y_sma: compute_dollars + .then(|| { + ComputedVecsFromDateIndex::forced_import( + &db, + "subsidy_usd_1y_sma", + Source::Compute, + version + v0, + indexes, + last(), + ) + }) + .transpose()?, + indexes_to_puell_multiple: compute_dollars + .then(|| { + ComputedVecsFromDateIndex::forced_import( + &db, + "puell_multiple", + Source::Compute, + version + v0, + indexes, + last(), + ) + }) + .transpose()?, + indexes_to_hash_rate: computed_h!("hash_rate", Source::Compute, v5, last()), + indexes_to_hash_rate_1w_sma: computed_di!("hash_rate_1w_sma", last()), + indexes_to_hash_rate_1m_sma: computed_di!("hash_rate_1m_sma", last()), + indexes_to_hash_rate_2m_sma: computed_di!("hash_rate_2m_sma", last()), + indexes_to_hash_rate_1y_sma: computed_di!("hash_rate_1y_sma", last()), + indexes_to_difficulty_as_hash: computed_h!( + "difficulty_as_hash", + Source::Compute, + last() + ), + indexes_to_difficulty_adjustment: computed_h!( + "difficulty_adjustment", + Source::Compute, + sum() + ), + indexes_to_blocks_before_next_difficulty_adjustment: computed_h!( + "blocks_before_next_difficulty_adjustment", + Source::Compute, + v2, + last() + ), + indexes_to_days_before_next_difficulty_adjustment: computed_h!( + "days_before_next_difficulty_adjustment", + Source::Compute, + v2, + last() + ), + indexes_to_blocks_before_next_halving: computed_h!( + "blocks_before_next_halving", + Source::Compute, + v2, + last() + ), + indexes_to_days_before_next_halving: computed_h!( + "days_before_next_halving", + Source::Compute, + v2, + last() + ), + indexes_to_hash_price_ths: computed_h!("hash_price_ths", Source::Compute, v4, last()), + indexes_to_hash_price_phs: computed_h!("hash_price_phs", Source::Compute, v4, last()), + indexes_to_hash_value_ths: computed_h!("hash_value_ths", Source::Compute, v4, last()), + indexes_to_hash_value_phs: computed_h!("hash_value_phs", Source::Compute, v4, last()), + indexes_to_hash_price_ths_min: computed_h!( + "hash_price_ths_min", + Source::Compute, + v4, + last() + ), + indexes_to_hash_price_phs_min: computed_h!( + "hash_price_phs_min", + Source::Compute, + v4, + last() + ), + indexes_to_hash_price_rebound: computed_h!( + "hash_price_rebound", + Source::Compute, + v4, + last() + ), + indexes_to_hash_value_ths_min: computed_h!( + "hash_value_ths_min", + Source::Compute, + v4, + last() + ), + indexes_to_hash_value_phs_min: computed_h!( + "hash_value_phs_min", + Source::Compute, + v4, + last() + ), + indexes_to_hash_value_rebound: computed_h!( + "hash_value_rebound", + Source::Compute, + v4, + last() + ), + indexes_to_inflation_rate: computed_di!("inflation_rate", last()), + indexes_to_annualized_volume: computed_di!("annualized_volume", last()), + indexes_to_annualized_volume_btc: computed_di!("annualized_volume_btc", last()), + indexes_to_annualized_volume_usd: computed_di!("annualized_volume_usd", last()), + indexes_to_tx_btc_velocity: computed_di!("tx_btc_velocity", last()), + indexes_to_tx_usd_velocity: computed_di!("tx_usd_velocity", last()), + indexes_to_tx_per_sec: computed_di!("tx_per_sec", v2, last()), + indexes_to_outputs_per_sec: computed_di!("outputs_per_sec", v2, last()), + indexes_to_inputs_per_sec: computed_di!("inputs_per_sec", v2, last()), + + txindex_to_is_coinbase, + txinindex_to_value, + txindex_to_input_value, + txindex_to_output_value, + txindex_to_fee, + txindex_to_fee_rate, + txindex_to_vsize, + txindex_to_weight, + + db, + }; + + this.db.retain_regions( + this.iter_any_exportable() + .flat_map(|v| v.region_names()) + .collect(), + )?; + + this.db.compact()?; + + Ok(this) + } +} diff --git a/crates/brk_computer/src/chain/mod.rs b/crates/brk_computer/src/chain/mod.rs new file mode 100644 index 000000000..1e6897cd8 --- /dev/null +++ b/crates/brk_computer/src/chain/mod.rs @@ -0,0 +1,132 @@ +mod compute; +mod import; + +use brk_traversable::Traversable; +use brk_types::{ + Bitcoin, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, FeeRate, HalvingEpoch, Height, + MonthIndex, QuarterIndex, Sats, SemesterIndex, StoredBool, StoredF32, StoredF64, StoredU32, + StoredU64, Timestamp, TxInIndex, TxIndex, VSize, WeekIndex, Weight, YearIndex, +}; +use vecdb::{Database, EagerVec, LazyVecFrom1, LazyVecFrom2, PcoVec}; + +use crate::grouped::{ + ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromDateIndex, + ComputedVecsFromHeight, ComputedVecsFromTxindex, +}; + +pub(crate) const TARGET_BLOCKS_PER_DAY_F64: f64 = 144.0; +pub(crate) const TARGET_BLOCKS_PER_DAY_F32: f32 = 144.0; +pub(crate) const TARGET_BLOCKS_PER_DAY: u64 = 144; +pub(crate) const TARGET_BLOCKS_PER_WEEK: u64 = 7 * TARGET_BLOCKS_PER_DAY; +pub(crate) const TARGET_BLOCKS_PER_MONTH: u64 = 30 * TARGET_BLOCKS_PER_DAY; +pub(crate) const TARGET_BLOCKS_PER_QUARTER: u64 = 3 * TARGET_BLOCKS_PER_MONTH; +pub(crate) const TARGET_BLOCKS_PER_SEMESTER: u64 = 2 * TARGET_BLOCKS_PER_QUARTER; +pub(crate) const TARGET_BLOCKS_PER_YEAR: u64 = 2 * TARGET_BLOCKS_PER_SEMESTER; +pub(crate) const TARGET_BLOCKS_PER_DECADE: u64 = 10 * TARGET_BLOCKS_PER_YEAR; +pub(crate) const ONE_TERA_HASH: f64 = 1_000_000_000_000.0; + +#[derive(Clone, Traversable)] +pub struct Vecs { + pub(crate) db: Database, + + pub dateindex_to_block_count_target: LazyVecFrom1, + pub weekindex_to_block_count_target: LazyVecFrom1, + pub monthindex_to_block_count_target: + LazyVecFrom1, + pub quarterindex_to_block_count_target: + LazyVecFrom1, + pub semesterindex_to_block_count_target: + LazyVecFrom1, + pub yearindex_to_block_count_target: LazyVecFrom1, + pub decadeindex_to_block_count_target: + LazyVecFrom1, + pub height_to_interval: EagerVec>, + pub height_to_24h_block_count: EagerVec>, + pub height_to_24h_coinbase_sum: EagerVec>, + pub height_to_24h_coinbase_usd_sum: EagerVec>, + pub height_to_vbytes: EagerVec>, + pub difficultyepoch_to_timestamp: EagerVec>, + pub halvingepoch_to_timestamp: EagerVec>, + pub timeindexes_to_timestamp: ComputedVecsFromDateIndex, + pub indexes_to_block_count: ComputedVecsFromHeight, + pub indexes_to_1w_block_count: ComputedVecsFromDateIndex, + pub indexes_to_1m_block_count: ComputedVecsFromDateIndex, + pub indexes_to_1y_block_count: ComputedVecsFromDateIndex, + pub indexes_to_block_interval: ComputedVecsFromHeight, + pub indexes_to_block_size: ComputedVecsFromHeight, + pub indexes_to_block_vbytes: ComputedVecsFromHeight, + pub indexes_to_block_weight: ComputedVecsFromHeight, + pub indexes_to_difficulty: ComputedVecsFromHeight, + pub indexes_to_difficultyepoch: ComputedVecsFromDateIndex, + pub indexes_to_halvingepoch: ComputedVecsFromDateIndex, + pub indexes_to_coinbase: ComputedValueVecsFromHeight, + pub indexes_to_emptyoutput_count: ComputedVecsFromHeight, + pub indexes_to_fee: ComputedValueVecsFromTxindex, + pub indexes_to_fee_rate: ComputedVecsFromTxindex, + /// Value == 0 when Coinbase + pub txindex_to_input_value: EagerVec>, + pub indexes_to_sent_sum: ComputedValueVecsFromHeight, + pub indexes_to_opreturn_count: ComputedVecsFromHeight, + pub txindex_to_output_value: EagerVec>, + pub indexes_to_p2a_count: ComputedVecsFromHeight, + pub indexes_to_p2ms_count: ComputedVecsFromHeight, + pub indexes_to_p2pk33_count: ComputedVecsFromHeight, + pub indexes_to_p2pk65_count: ComputedVecsFromHeight, + pub indexes_to_p2pkh_count: ComputedVecsFromHeight, + pub indexes_to_p2sh_count: ComputedVecsFromHeight, + pub indexes_to_p2tr_count: ComputedVecsFromHeight, + pub indexes_to_p2wpkh_count: ComputedVecsFromHeight, + pub indexes_to_p2wsh_count: ComputedVecsFromHeight, + pub indexes_to_subsidy: ComputedValueVecsFromHeight, + pub indexes_to_unclaimed_rewards: ComputedValueVecsFromHeight, + pub indexes_to_tx_count: ComputedVecsFromHeight, + pub indexes_to_tx_v1: ComputedVecsFromHeight, + pub indexes_to_tx_v2: ComputedVecsFromHeight, + pub indexes_to_tx_v3: ComputedVecsFromHeight, + pub indexes_to_tx_vsize: ComputedVecsFromTxindex, + pub indexes_to_tx_weight: ComputedVecsFromTxindex, + pub indexes_to_unknownoutput_count: ComputedVecsFromHeight, + pub txinindex_to_value: EagerVec>, + pub indexes_to_input_count: ComputedVecsFromTxindex, + pub txindex_to_is_coinbase: LazyVecFrom2, + pub indexes_to_output_count: ComputedVecsFromTxindex, + pub txindex_to_vsize: LazyVecFrom1, + pub txindex_to_weight: LazyVecFrom2, + pub txindex_to_fee: EagerVec>, + pub txindex_to_fee_rate: EagerVec>, + pub indexes_to_exact_utxo_count: ComputedVecsFromHeight, + pub dateindex_to_fee_dominance: EagerVec>, + pub dateindex_to_subsidy_dominance: EagerVec>, + pub indexes_to_subsidy_usd_1y_sma: Option>, + pub indexes_to_puell_multiple: Option>, + pub indexes_to_hash_rate: ComputedVecsFromHeight, + pub indexes_to_hash_rate_1w_sma: ComputedVecsFromDateIndex, + pub indexes_to_hash_rate_1m_sma: ComputedVecsFromDateIndex, + pub indexes_to_hash_rate_2m_sma: ComputedVecsFromDateIndex, + pub indexes_to_hash_rate_1y_sma: ComputedVecsFromDateIndex, + pub indexes_to_hash_price_ths: ComputedVecsFromHeight, + pub indexes_to_hash_price_ths_min: ComputedVecsFromHeight, + pub indexes_to_hash_price_phs: ComputedVecsFromHeight, + pub indexes_to_hash_price_phs_min: ComputedVecsFromHeight, + pub indexes_to_hash_price_rebound: ComputedVecsFromHeight, + pub indexes_to_hash_value_ths: ComputedVecsFromHeight, + pub indexes_to_hash_value_ths_min: ComputedVecsFromHeight, + pub indexes_to_hash_value_phs: ComputedVecsFromHeight, + pub indexes_to_hash_value_phs_min: ComputedVecsFromHeight, + pub indexes_to_hash_value_rebound: ComputedVecsFromHeight, + pub indexes_to_difficulty_as_hash: ComputedVecsFromHeight, + pub indexes_to_difficulty_adjustment: ComputedVecsFromHeight, + pub indexes_to_blocks_before_next_difficulty_adjustment: ComputedVecsFromHeight, + pub indexes_to_days_before_next_difficulty_adjustment: ComputedVecsFromHeight, + pub indexes_to_blocks_before_next_halving: ComputedVecsFromHeight, + pub indexes_to_days_before_next_halving: ComputedVecsFromHeight, + pub indexes_to_inflation_rate: ComputedVecsFromDateIndex, + pub indexes_to_annualized_volume: ComputedVecsFromDateIndex, + pub indexes_to_annualized_volume_btc: ComputedVecsFromDateIndex, + pub indexes_to_annualized_volume_usd: ComputedVecsFromDateIndex, + pub indexes_to_tx_btc_velocity: ComputedVecsFromDateIndex, + pub indexes_to_tx_usd_velocity: ComputedVecsFromDateIndex, + pub indexes_to_tx_per_sec: ComputedVecsFromDateIndex, + pub indexes_to_outputs_per_sec: ComputedVecsFromDateIndex, + pub indexes_to_inputs_per_sec: ComputedVecsFromDateIndex, +} diff --git a/crates/brk_computer/src/market.rs b/crates/brk_computer/src/market/compute.rs similarity index 52% rename from crates/brk_computer/src/market.rs rename to crates/brk_computer/src/market/compute.rs index ffbf9ba22..366da226d 100644 --- a/crates/brk_computer/src/market.rs +++ b/crates/brk_computer/src/market/compute.rs @@ -1,438 +1,19 @@ -use std::{path::Path, thread}; +use std::thread; use brk_error::Result; -use brk_traversable::Traversable; -use brk_types::{Date, DateIndex, Dollars, Height, Sats, StoredF32, StoredU16, Version}; -use vecdb::{ - Database, EagerVec, Exit, GenericStoredVec, ImportableVec, PAGE_SIZE, PcoVec, TypedVecIterator, - VecIndex, -}; +use brk_types::{Date, DateIndex, Dollars, StoredF32, StoredU16}; +use vecdb::{EagerVec, Exit, GenericStoredVec, PcoVec, TypedVecIterator, VecIndex}; use crate::{ - grouped::{ComputedStandardDeviationVecsFromDateIndex, Source, StandardDeviationVecsOptions}, price, traits::{ComputeDCAAveragePriceViaLen, ComputeDCAStackViaLen, ComputeDrawdown}, utils::OptionExt, -}; - -use super::{ Indexes, - grouped::{ComputedRatioVecsFromDateIndex, ComputedVecsFromDateIndex, VecBuilderOptions}, - indexes, }; -#[derive(Clone, Traversable)] -pub struct Vecs { - db: Database, - - pub height_to_price_ath: EagerVec>, - pub height_to_price_drawdown: EagerVec>, - pub indexes_to_price_ath: ComputedVecsFromDateIndex, - pub indexes_to_price_drawdown: ComputedVecsFromDateIndex, - pub indexes_to_days_since_price_ath: ComputedVecsFromDateIndex, - pub indexes_to_max_days_between_price_aths: ComputedVecsFromDateIndex, - pub indexes_to_max_years_between_price_aths: ComputedVecsFromDateIndex, - - pub indexes_to_1d_returns_1w_sd: ComputedStandardDeviationVecsFromDateIndex, - pub indexes_to_1d_returns_1m_sd: ComputedStandardDeviationVecsFromDateIndex, - pub indexes_to_1d_returns_1y_sd: ComputedStandardDeviationVecsFromDateIndex, - pub indexes_to_price_1w_volatility: ComputedVecsFromDateIndex, - pub indexes_to_price_1m_volatility: ComputedVecsFromDateIndex, - pub indexes_to_price_1y_volatility: ComputedVecsFromDateIndex, - - pub indexes_to_price_1w_min: ComputedVecsFromDateIndex, - pub indexes_to_price_1w_max: ComputedVecsFromDateIndex, - pub indexes_to_price_2w_min: ComputedVecsFromDateIndex, - pub indexes_to_price_2w_max: ComputedVecsFromDateIndex, - pub indexes_to_price_1m_min: ComputedVecsFromDateIndex, - pub indexes_to_price_1m_max: ComputedVecsFromDateIndex, - pub indexes_to_price_1y_min: ComputedVecsFromDateIndex, - pub indexes_to_price_1y_max: ComputedVecsFromDateIndex, - - pub dateindex_to_price_true_range: EagerVec>, - pub dateindex_to_price_true_range_2w_sum: EagerVec>, - pub indexes_to_price_2w_choppiness_index: ComputedVecsFromDateIndex, - - pub indexes_to_price_1w_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_8d_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_13d_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_21d_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_1m_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_34d_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_55d_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_89d_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_144d_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_200d_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_1y_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_2y_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_200w_sma: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_4y_sma: ComputedRatioVecsFromDateIndex, - - pub indexes_to_price_1w_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_8d_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_13d_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_21d_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_1m_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_34d_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_55d_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_89d_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_144d_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_200d_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_1y_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_2y_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_200w_ema: ComputedRatioVecsFromDateIndex, - pub indexes_to_price_4y_ema: ComputedRatioVecsFromDateIndex, - - pub indexes_to_price_200d_sma_x2_4: ComputedVecsFromDateIndex, - pub indexes_to_price_200d_sma_x0_8: ComputedVecsFromDateIndex, - - pub price_1d_ago: ComputedVecsFromDateIndex, - pub price_1w_ago: ComputedVecsFromDateIndex, - pub price_1m_ago: ComputedVecsFromDateIndex, - pub price_3m_ago: ComputedVecsFromDateIndex, - pub price_6m_ago: ComputedVecsFromDateIndex, - pub price_1y_ago: ComputedVecsFromDateIndex, - pub price_2y_ago: ComputedVecsFromDateIndex, - pub price_3y_ago: ComputedVecsFromDateIndex, - pub price_4y_ago: ComputedVecsFromDateIndex, - pub price_5y_ago: ComputedVecsFromDateIndex, - pub price_6y_ago: ComputedVecsFromDateIndex, - pub price_8y_ago: ComputedVecsFromDateIndex, - pub price_10y_ago: ComputedVecsFromDateIndex, - - pub _1d_price_returns: ComputedVecsFromDateIndex, - pub _1w_price_returns: ComputedVecsFromDateIndex, - pub _1m_price_returns: ComputedVecsFromDateIndex, - pub _3m_price_returns: ComputedVecsFromDateIndex, - pub _6m_price_returns: ComputedVecsFromDateIndex, - pub _1y_price_returns: ComputedVecsFromDateIndex, - pub _2y_price_returns: ComputedVecsFromDateIndex, - pub _3y_price_returns: ComputedVecsFromDateIndex, - pub _4y_price_returns: ComputedVecsFromDateIndex, - pub _5y_price_returns: ComputedVecsFromDateIndex, - pub _6y_price_returns: ComputedVecsFromDateIndex, - pub _8y_price_returns: ComputedVecsFromDateIndex, - pub _10y_price_returns: ComputedVecsFromDateIndex, - pub _2y_cagr: ComputedVecsFromDateIndex, - pub _3y_cagr: ComputedVecsFromDateIndex, - pub _4y_cagr: ComputedVecsFromDateIndex, - pub _5y_cagr: ComputedVecsFromDateIndex, - pub _6y_cagr: ComputedVecsFromDateIndex, - pub _8y_cagr: ComputedVecsFromDateIndex, - pub _10y_cagr: ComputedVecsFromDateIndex, - - pub _1w_dca_stack: ComputedVecsFromDateIndex, - pub _1m_dca_stack: ComputedVecsFromDateIndex, - pub _3m_dca_stack: ComputedVecsFromDateIndex, - pub _6m_dca_stack: ComputedVecsFromDateIndex, - pub _1y_dca_stack: ComputedVecsFromDateIndex, - pub _2y_dca_stack: ComputedVecsFromDateIndex, - pub _3y_dca_stack: ComputedVecsFromDateIndex, - pub _4y_dca_stack: ComputedVecsFromDateIndex, - pub _5y_dca_stack: ComputedVecsFromDateIndex, - pub _6y_dca_stack: ComputedVecsFromDateIndex, - pub _8y_dca_stack: ComputedVecsFromDateIndex, - pub _10y_dca_stack: ComputedVecsFromDateIndex, - pub _1w_dca_avg_price: ComputedVecsFromDateIndex, - pub _1m_dca_avg_price: ComputedVecsFromDateIndex, - pub _3m_dca_avg_price: ComputedVecsFromDateIndex, - pub _6m_dca_avg_price: ComputedVecsFromDateIndex, - pub _1y_dca_avg_price: ComputedVecsFromDateIndex, - pub _2y_dca_avg_price: ComputedVecsFromDateIndex, - pub _3y_dca_avg_price: ComputedVecsFromDateIndex, - pub _4y_dca_avg_price: ComputedVecsFromDateIndex, - pub _5y_dca_avg_price: ComputedVecsFromDateIndex, - pub _6y_dca_avg_price: ComputedVecsFromDateIndex, - pub _8y_dca_avg_price: ComputedVecsFromDateIndex, - pub _10y_dca_avg_price: ComputedVecsFromDateIndex, - pub _1w_dca_returns: ComputedVecsFromDateIndex, - pub _1m_dca_returns: ComputedVecsFromDateIndex, - pub _3m_dca_returns: ComputedVecsFromDateIndex, - pub _6m_dca_returns: ComputedVecsFromDateIndex, - pub _1y_dca_returns: ComputedVecsFromDateIndex, - pub _2y_dca_returns: ComputedVecsFromDateIndex, - pub _3y_dca_returns: ComputedVecsFromDateIndex, - pub _4y_dca_returns: ComputedVecsFromDateIndex, - pub _5y_dca_returns: ComputedVecsFromDateIndex, - pub _6y_dca_returns: ComputedVecsFromDateIndex, - pub _8y_dca_returns: ComputedVecsFromDateIndex, - pub _10y_dca_returns: ComputedVecsFromDateIndex, - pub _2y_dca_cagr: ComputedVecsFromDateIndex, - pub _3y_dca_cagr: ComputedVecsFromDateIndex, - pub _4y_dca_cagr: ComputedVecsFromDateIndex, - pub _5y_dca_cagr: ComputedVecsFromDateIndex, - pub _6y_dca_cagr: ComputedVecsFromDateIndex, - pub _8y_dca_cagr: ComputedVecsFromDateIndex, - pub _10y_dca_cagr: ComputedVecsFromDateIndex, - - pub dca_class_2025_stack: ComputedVecsFromDateIndex, - pub dca_class_2024_stack: ComputedVecsFromDateIndex, - pub dca_class_2023_stack: ComputedVecsFromDateIndex, - pub dca_class_2022_stack: ComputedVecsFromDateIndex, - pub dca_class_2021_stack: ComputedVecsFromDateIndex, - pub dca_class_2020_stack: ComputedVecsFromDateIndex, - pub dca_class_2019_stack: ComputedVecsFromDateIndex, - pub dca_class_2018_stack: ComputedVecsFromDateIndex, - pub dca_class_2017_stack: ComputedVecsFromDateIndex, - pub dca_class_2016_stack: ComputedVecsFromDateIndex, - pub dca_class_2015_stack: ComputedVecsFromDateIndex, - - pub dca_class_2025_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2024_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2023_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2022_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2021_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2020_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2019_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2018_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2017_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2016_avg_price: ComputedVecsFromDateIndex, - pub dca_class_2015_avg_price: ComputedVecsFromDateIndex, - - pub dca_class_2025_returns: ComputedVecsFromDateIndex, - pub dca_class_2024_returns: ComputedVecsFromDateIndex, - pub dca_class_2023_returns: ComputedVecsFromDateIndex, - pub dca_class_2022_returns: ComputedVecsFromDateIndex, - pub dca_class_2021_returns: ComputedVecsFromDateIndex, - pub dca_class_2020_returns: ComputedVecsFromDateIndex, - pub dca_class_2019_returns: ComputedVecsFromDateIndex, - pub dca_class_2018_returns: ComputedVecsFromDateIndex, - pub dca_class_2017_returns: ComputedVecsFromDateIndex, - pub dca_class_2016_returns: ComputedVecsFromDateIndex, - pub dca_class_2015_returns: ComputedVecsFromDateIndex, -} +use super::Vecs; impl Vecs { - pub fn forced_import( - parent_path: &Path, - parent_version: Version, - indexes: &indexes::Vecs, - ) -> Result { - let db = Database::open(&parent_path.join("market"))?; - db.set_min_len(PAGE_SIZE * 1_000_000)?; - - let version = parent_version + Version::ZERO; - let v0 = Version::ZERO; - let v1 = Version::ONE; - let v2 = Version::TWO; - let last = VecBuilderOptions::default().add_last(); - - // Helper macros for computed vecs - macro_rules! computed_di { - ($name:expr) => { - ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + v0, indexes, last.clone())? - }; - ($name:expr, $v:expr) => { - ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + $v, indexes, last.clone())? - }; - } - macro_rules! ratio_di { - ($name:expr) => { - ComputedRatioVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + v0, indexes, true)? - }; - } - macro_rules! sd_di { - ($name:expr, $window:expr, $v:expr) => { - ComputedStandardDeviationVecsFromDateIndex::forced_import(&db, $name, $window, Source::Compute, version + $v, indexes, StandardDeviationVecsOptions::default())? - }; - } - macro_rules! eager_h { - ($name:expr, $v:expr) => { - EagerVec::forced_import(&db, $name, version + $v)? - }; - } - macro_rules! eager_di { - ($name:expr, $v:expr) => { - EagerVec::forced_import(&db, $name, version + $v)? - }; - } - - let this = Self { - height_to_price_ath: eager_h!("price_ath", v0), - height_to_price_drawdown: eager_h!("price_drawdown", v0), - indexes_to_price_ath: computed_di!("price_ath"), - indexes_to_price_drawdown: computed_di!("price_drawdown"), - indexes_to_1d_returns_1w_sd: sd_di!("1d_returns_1w_sd", 7, v1), - indexes_to_1d_returns_1m_sd: sd_di!("1d_returns_1m_sd", 30, v1), - indexes_to_1d_returns_1y_sd: sd_di!("1d_returns_1y_sd", 365, v1), - indexes_to_price_1w_volatility: computed_di!("price_1w_volatility", v2), - indexes_to_price_1m_volatility: computed_di!("price_1m_volatility", v2), - indexes_to_price_1y_volatility: computed_di!("price_1y_volatility", v2), - indexes_to_days_since_price_ath: computed_di!("days_since_price_ath"), - indexes_to_max_days_between_price_aths: computed_di!("max_days_between_price_aths"), - indexes_to_max_years_between_price_aths: computed_di!("max_years_between_price_aths"), - - indexes_to_price_1w_sma: ratio_di!("price_1w_sma"), - indexes_to_price_8d_sma: ratio_di!("price_8d_sma"), - indexes_to_price_13d_sma: ratio_di!("price_13d_sma"), - indexes_to_price_21d_sma: ratio_di!("price_21d_sma"), - indexes_to_price_1m_sma: ratio_di!("price_1m_sma"), - indexes_to_price_34d_sma: ratio_di!("price_34d_sma"), - indexes_to_price_55d_sma: ratio_di!("price_55d_sma"), - indexes_to_price_89d_sma: ratio_di!("price_89d_sma"), - indexes_to_price_144d_sma: ratio_di!("price_144d_sma"), - indexes_to_price_200d_sma: ratio_di!("price_200d_sma"), - indexes_to_price_1y_sma: ratio_di!("price_1y_sma"), - indexes_to_price_2y_sma: ratio_di!("price_2y_sma"), - indexes_to_price_200w_sma: ratio_di!("price_200w_sma"), - indexes_to_price_4y_sma: ratio_di!("price_4y_sma"), - - indexes_to_price_1w_ema: ratio_di!("price_1w_ema"), - indexes_to_price_8d_ema: ratio_di!("price_8d_ema"), - indexes_to_price_13d_ema: ratio_di!("price_13d_ema"), - indexes_to_price_21d_ema: ratio_di!("price_21d_ema"), - indexes_to_price_1m_ema: ratio_di!("price_1m_ema"), - indexes_to_price_34d_ema: ratio_di!("price_34d_ema"), - indexes_to_price_55d_ema: ratio_di!("price_55d_ema"), - indexes_to_price_89d_ema: ratio_di!("price_89d_ema"), - indexes_to_price_144d_ema: ratio_di!("price_144d_ema"), - indexes_to_price_200d_ema: ratio_di!("price_200d_ema"), - indexes_to_price_1y_ema: ratio_di!("price_1y_ema"), - indexes_to_price_2y_ema: ratio_di!("price_2y_ema"), - indexes_to_price_200w_ema: ratio_di!("price_200w_ema"), - indexes_to_price_4y_ema: ratio_di!("price_4y_ema"), - - _1d_price_returns: computed_di!("1d_price_returns"), - _1w_price_returns: computed_di!("1w_price_returns"), - _1m_price_returns: computed_di!("1m_price_returns"), - _3m_price_returns: computed_di!("3m_price_returns"), - _6m_price_returns: computed_di!("6m_price_returns"), - _1y_price_returns: computed_di!("1y_price_returns"), - _2y_price_returns: computed_di!("2y_price_returns"), - _3y_price_returns: computed_di!("3y_price_returns"), - _4y_price_returns: computed_di!("4y_price_returns"), - _5y_price_returns: computed_di!("5y_price_returns"), - _6y_price_returns: computed_di!("6y_price_returns"), - _8y_price_returns: computed_di!("8y_price_returns"), - _10y_price_returns: computed_di!("10y_price_returns"), - _2y_cagr: computed_di!("2y_cagr"), - _3y_cagr: computed_di!("3y_cagr"), - _4y_cagr: computed_di!("4y_cagr"), - _5y_cagr: computed_di!("5y_cagr"), - _6y_cagr: computed_di!("6y_cagr"), - _8y_cagr: computed_di!("8y_cagr"), - _10y_cagr: computed_di!("10y_cagr"), - - _1w_dca_returns: computed_di!("1w_dca_returns"), - _1m_dca_returns: computed_di!("1m_dca_returns"), - _3m_dca_returns: computed_di!("3m_dca_returns"), - _6m_dca_returns: computed_di!("6m_dca_returns"), - _1y_dca_returns: computed_di!("1y_dca_returns"), - _2y_dca_returns: computed_di!("2y_dca_returns"), - _3y_dca_returns: computed_di!("3y_dca_returns"), - _4y_dca_returns: computed_di!("4y_dca_returns"), - _5y_dca_returns: computed_di!("5y_dca_returns"), - _6y_dca_returns: computed_di!("6y_dca_returns"), - _8y_dca_returns: computed_di!("8y_dca_returns"), - _10y_dca_returns: computed_di!("10y_dca_returns"), - _2y_dca_cagr: computed_di!("2y_dca_cagr"), - _3y_dca_cagr: computed_di!("3y_dca_cagr"), - _4y_dca_cagr: computed_di!("4y_dca_cagr"), - _5y_dca_cagr: computed_di!("5y_dca_cagr"), - _6y_dca_cagr: computed_di!("6y_dca_cagr"), - _8y_dca_cagr: computed_di!("8y_dca_cagr"), - _10y_dca_cagr: computed_di!("10y_dca_cagr"), - _1w_dca_avg_price: computed_di!("1w_dca_avg_price"), - _1m_dca_avg_price: computed_di!("1m_dca_avg_price"), - _3m_dca_avg_price: computed_di!("3m_dca_avg_price"), - _6m_dca_avg_price: computed_di!("6m_dca_avg_price"), - _1y_dca_avg_price: computed_di!("1y_dca_avg_price"), - _2y_dca_avg_price: computed_di!("2y_dca_avg_price"), - _3y_dca_avg_price: computed_di!("3y_dca_avg_price"), - _4y_dca_avg_price: computed_di!("4y_dca_avg_price"), - _5y_dca_avg_price: computed_di!("5y_dca_avg_price"), - _6y_dca_avg_price: computed_di!("6y_dca_avg_price"), - _8y_dca_avg_price: computed_di!("8y_dca_avg_price"), - _10y_dca_avg_price: computed_di!("10y_dca_avg_price"), - price_1d_ago: computed_di!("price_1d_ago"), - price_1w_ago: computed_di!("price_1w_ago"), - price_1m_ago: computed_di!("price_1m_ago"), - price_3m_ago: computed_di!("price_3m_ago"), - price_6m_ago: computed_di!("price_6m_ago"), - price_1y_ago: computed_di!("price_1y_ago"), - price_2y_ago: computed_di!("price_2y_ago"), - price_3y_ago: computed_di!("price_3y_ago"), - price_4y_ago: computed_di!("price_4y_ago"), - price_5y_ago: computed_di!("price_5y_ago"), - price_6y_ago: computed_di!("price_6y_ago"), - price_8y_ago: computed_di!("price_8y_ago"), - price_10y_ago: computed_di!("price_10y_ago"), - _1w_dca_stack: computed_di!("1w_dca_stack"), - _1m_dca_stack: computed_di!("1m_dca_stack"), - _3m_dca_stack: computed_di!("3m_dca_stack"), - _6m_dca_stack: computed_di!("6m_dca_stack"), - _1y_dca_stack: computed_di!("1y_dca_stack"), - _2y_dca_stack: computed_di!("2y_dca_stack"), - _3y_dca_stack: computed_di!("3y_dca_stack"), - _4y_dca_stack: computed_di!("4y_dca_stack"), - _5y_dca_stack: computed_di!("5y_dca_stack"), - _6y_dca_stack: computed_di!("6y_dca_stack"), - _8y_dca_stack: computed_di!("8y_dca_stack"), - _10y_dca_stack: computed_di!("10y_dca_stack"), - - dca_class_2025_stack: computed_di!("dca_class_2025_stack"), - dca_class_2024_stack: computed_di!("dca_class_2024_stack"), - dca_class_2023_stack: computed_di!("dca_class_2023_stack"), - dca_class_2022_stack: computed_di!("dca_class_2022_stack"), - dca_class_2021_stack: computed_di!("dca_class_2021_stack"), - dca_class_2020_stack: computed_di!("dca_class_2020_stack"), - dca_class_2019_stack: computed_di!("dca_class_2019_stack"), - dca_class_2018_stack: computed_di!("dca_class_2018_stack"), - dca_class_2017_stack: computed_di!("dca_class_2017_stack"), - dca_class_2016_stack: computed_di!("dca_class_2016_stack"), - dca_class_2015_stack: computed_di!("dca_class_2015_stack"), - - dca_class_2025_avg_price: computed_di!("dca_class_2025_avg_price"), - dca_class_2024_avg_price: computed_di!("dca_class_2024_avg_price"), - dca_class_2023_avg_price: computed_di!("dca_class_2023_avg_price"), - dca_class_2022_avg_price: computed_di!("dca_class_2022_avg_price"), - dca_class_2021_avg_price: computed_di!("dca_class_2021_avg_price"), - dca_class_2020_avg_price: computed_di!("dca_class_2020_avg_price"), - dca_class_2019_avg_price: computed_di!("dca_class_2019_avg_price"), - dca_class_2018_avg_price: computed_di!("dca_class_2018_avg_price"), - dca_class_2017_avg_price: computed_di!("dca_class_2017_avg_price"), - dca_class_2016_avg_price: computed_di!("dca_class_2016_avg_price"), - dca_class_2015_avg_price: computed_di!("dca_class_2015_avg_price"), - - dca_class_2025_returns: computed_di!("dca_class_2025_returns"), - dca_class_2024_returns: computed_di!("dca_class_2024_returns"), - dca_class_2023_returns: computed_di!("dca_class_2023_returns"), - dca_class_2022_returns: computed_di!("dca_class_2022_returns"), - dca_class_2021_returns: computed_di!("dca_class_2021_returns"), - dca_class_2020_returns: computed_di!("dca_class_2020_returns"), - dca_class_2019_returns: computed_di!("dca_class_2019_returns"), - dca_class_2018_returns: computed_di!("dca_class_2018_returns"), - dca_class_2017_returns: computed_di!("dca_class_2017_returns"), - dca_class_2016_returns: computed_di!("dca_class_2016_returns"), - dca_class_2015_returns: computed_di!("dca_class_2015_returns"), - - indexes_to_price_200d_sma_x2_4: computed_di!("price_200d_sma_x2_4"), - indexes_to_price_200d_sma_x0_8: computed_di!("price_200d_sma_x0_8"), - dateindex_to_price_true_range: eager_di!("price_true_range", v0), - dateindex_to_price_true_range_2w_sum: eager_di!("price_true_range_2w_sum", v0), - indexes_to_price_1w_min: computed_di!("price_1w_min", v1), - indexes_to_price_1w_max: computed_di!("price_1w_max", v1), - indexes_to_price_2w_min: computed_di!("price_2w_min", v1), - indexes_to_price_2w_max: computed_di!("price_2w_max", v1), - indexes_to_price_1m_min: computed_di!("price_1m_min", v1), - indexes_to_price_1m_max: computed_di!("price_1m_max", v1), - indexes_to_price_1y_min: computed_di!("price_1y_min", v1), - indexes_to_price_1y_max: computed_di!("price_1y_max", v1), - indexes_to_price_2w_choppiness_index: computed_di!("price_2w_choppiness_index", v1), - db, - }; - - this.db.retain_regions( - this.iter_any_exportable() - .flat_map(|v| v.region_names()) - .collect(), - )?; - - this.db.compact()?; - - Ok(this) - } - pub fn compute( &mut self, price: &price::Vecs, diff --git a/crates/brk_computer/src/market/import.rs b/crates/brk_computer/src/market/import.rs new file mode 100644 index 000000000..ceea5380c --- /dev/null +++ b/crates/brk_computer/src/market/import.rs @@ -0,0 +1,247 @@ +use std::path::Path; + +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::Version; +use vecdb::{Database, EagerVec, ImportableVec, PAGE_SIZE}; + +use crate::{ + grouped::{ + ComputedRatioVecsFromDateIndex, ComputedStandardDeviationVecsFromDateIndex, + ComputedVecsFromDateIndex, Source, StandardDeviationVecsOptions, VecBuilderOptions, + }, + indexes, +}; + +use super::Vecs; + +impl Vecs { + pub fn forced_import( + parent_path: &Path, + parent_version: Version, + indexes: &indexes::Vecs, + ) -> Result { + let db = Database::open(&parent_path.join("market"))?; + db.set_min_len(PAGE_SIZE * 1_000_000)?; + + let version = parent_version + Version::ZERO; + let v0 = Version::ZERO; + let v1 = Version::ONE; + let v2 = Version::TWO; + let last = VecBuilderOptions::default().add_last(); + + macro_rules! computed_di { + ($name:expr) => { + ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + v0, indexes, last.clone())? + }; + ($name:expr, $v:expr) => { + ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + $v, indexes, last.clone())? + }; + } + macro_rules! ratio_di { + ($name:expr) => { + ComputedRatioVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + v0, indexes, true)? + }; + } + macro_rules! sd_di { + ($name:expr, $window:expr, $v:expr) => { + ComputedStandardDeviationVecsFromDateIndex::forced_import(&db, $name, $window, Source::Compute, version + $v, indexes, StandardDeviationVecsOptions::default())? + }; + } + macro_rules! eager_h { + ($name:expr, $v:expr) => { + EagerVec::forced_import(&db, $name, version + $v)? + }; + } + macro_rules! eager_di { + ($name:expr, $v:expr) => { + EagerVec::forced_import(&db, $name, version + $v)? + }; + } + + let this = Self { + height_to_price_ath: eager_h!("price_ath", v0), + height_to_price_drawdown: eager_h!("price_drawdown", v0), + indexes_to_price_ath: computed_di!("price_ath"), + indexes_to_price_drawdown: computed_di!("price_drawdown"), + indexes_to_1d_returns_1w_sd: sd_di!("1d_returns_1w_sd", 7, v1), + indexes_to_1d_returns_1m_sd: sd_di!("1d_returns_1m_sd", 30, v1), + indexes_to_1d_returns_1y_sd: sd_di!("1d_returns_1y_sd", 365, v1), + indexes_to_price_1w_volatility: computed_di!("price_1w_volatility", v2), + indexes_to_price_1m_volatility: computed_di!("price_1m_volatility", v2), + indexes_to_price_1y_volatility: computed_di!("price_1y_volatility", v2), + indexes_to_days_since_price_ath: computed_di!("days_since_price_ath"), + indexes_to_max_days_between_price_aths: computed_di!("max_days_between_price_aths"), + indexes_to_max_years_between_price_aths: computed_di!("max_years_between_price_aths"), + + indexes_to_price_1w_sma: ratio_di!("price_1w_sma"), + indexes_to_price_8d_sma: ratio_di!("price_8d_sma"), + indexes_to_price_13d_sma: ratio_di!("price_13d_sma"), + indexes_to_price_21d_sma: ratio_di!("price_21d_sma"), + indexes_to_price_1m_sma: ratio_di!("price_1m_sma"), + indexes_to_price_34d_sma: ratio_di!("price_34d_sma"), + indexes_to_price_55d_sma: ratio_di!("price_55d_sma"), + indexes_to_price_89d_sma: ratio_di!("price_89d_sma"), + indexes_to_price_144d_sma: ratio_di!("price_144d_sma"), + indexes_to_price_200d_sma: ratio_di!("price_200d_sma"), + indexes_to_price_1y_sma: ratio_di!("price_1y_sma"), + indexes_to_price_2y_sma: ratio_di!("price_2y_sma"), + indexes_to_price_200w_sma: ratio_di!("price_200w_sma"), + indexes_to_price_4y_sma: ratio_di!("price_4y_sma"), + + indexes_to_price_1w_ema: ratio_di!("price_1w_ema"), + indexes_to_price_8d_ema: ratio_di!("price_8d_ema"), + indexes_to_price_13d_ema: ratio_di!("price_13d_ema"), + indexes_to_price_21d_ema: ratio_di!("price_21d_ema"), + indexes_to_price_1m_ema: ratio_di!("price_1m_ema"), + indexes_to_price_34d_ema: ratio_di!("price_34d_ema"), + indexes_to_price_55d_ema: ratio_di!("price_55d_ema"), + indexes_to_price_89d_ema: ratio_di!("price_89d_ema"), + indexes_to_price_144d_ema: ratio_di!("price_144d_ema"), + indexes_to_price_200d_ema: ratio_di!("price_200d_ema"), + indexes_to_price_1y_ema: ratio_di!("price_1y_ema"), + indexes_to_price_2y_ema: ratio_di!("price_2y_ema"), + indexes_to_price_200w_ema: ratio_di!("price_200w_ema"), + indexes_to_price_4y_ema: ratio_di!("price_4y_ema"), + + _1d_price_returns: computed_di!("1d_price_returns"), + _1w_price_returns: computed_di!("1w_price_returns"), + _1m_price_returns: computed_di!("1m_price_returns"), + _3m_price_returns: computed_di!("3m_price_returns"), + _6m_price_returns: computed_di!("6m_price_returns"), + _1y_price_returns: computed_di!("1y_price_returns"), + _2y_price_returns: computed_di!("2y_price_returns"), + _3y_price_returns: computed_di!("3y_price_returns"), + _4y_price_returns: computed_di!("4y_price_returns"), + _5y_price_returns: computed_di!("5y_price_returns"), + _6y_price_returns: computed_di!("6y_price_returns"), + _8y_price_returns: computed_di!("8y_price_returns"), + _10y_price_returns: computed_di!("10y_price_returns"), + _2y_cagr: computed_di!("2y_cagr"), + _3y_cagr: computed_di!("3y_cagr"), + _4y_cagr: computed_di!("4y_cagr"), + _5y_cagr: computed_di!("5y_cagr"), + _6y_cagr: computed_di!("6y_cagr"), + _8y_cagr: computed_di!("8y_cagr"), + _10y_cagr: computed_di!("10y_cagr"), + + _1w_dca_returns: computed_di!("1w_dca_returns"), + _1m_dca_returns: computed_di!("1m_dca_returns"), + _3m_dca_returns: computed_di!("3m_dca_returns"), + _6m_dca_returns: computed_di!("6m_dca_returns"), + _1y_dca_returns: computed_di!("1y_dca_returns"), + _2y_dca_returns: computed_di!("2y_dca_returns"), + _3y_dca_returns: computed_di!("3y_dca_returns"), + _4y_dca_returns: computed_di!("4y_dca_returns"), + _5y_dca_returns: computed_di!("5y_dca_returns"), + _6y_dca_returns: computed_di!("6y_dca_returns"), + _8y_dca_returns: computed_di!("8y_dca_returns"), + _10y_dca_returns: computed_di!("10y_dca_returns"), + _2y_dca_cagr: computed_di!("2y_dca_cagr"), + _3y_dca_cagr: computed_di!("3y_dca_cagr"), + _4y_dca_cagr: computed_di!("4y_dca_cagr"), + _5y_dca_cagr: computed_di!("5y_dca_cagr"), + _6y_dca_cagr: computed_di!("6y_dca_cagr"), + _8y_dca_cagr: computed_di!("8y_dca_cagr"), + _10y_dca_cagr: computed_di!("10y_dca_cagr"), + _1w_dca_avg_price: computed_di!("1w_dca_avg_price"), + _1m_dca_avg_price: computed_di!("1m_dca_avg_price"), + _3m_dca_avg_price: computed_di!("3m_dca_avg_price"), + _6m_dca_avg_price: computed_di!("6m_dca_avg_price"), + _1y_dca_avg_price: computed_di!("1y_dca_avg_price"), + _2y_dca_avg_price: computed_di!("2y_dca_avg_price"), + _3y_dca_avg_price: computed_di!("3y_dca_avg_price"), + _4y_dca_avg_price: computed_di!("4y_dca_avg_price"), + _5y_dca_avg_price: computed_di!("5y_dca_avg_price"), + _6y_dca_avg_price: computed_di!("6y_dca_avg_price"), + _8y_dca_avg_price: computed_di!("8y_dca_avg_price"), + _10y_dca_avg_price: computed_di!("10y_dca_avg_price"), + price_1d_ago: computed_di!("price_1d_ago"), + price_1w_ago: computed_di!("price_1w_ago"), + price_1m_ago: computed_di!("price_1m_ago"), + price_3m_ago: computed_di!("price_3m_ago"), + price_6m_ago: computed_di!("price_6m_ago"), + price_1y_ago: computed_di!("price_1y_ago"), + price_2y_ago: computed_di!("price_2y_ago"), + price_3y_ago: computed_di!("price_3y_ago"), + price_4y_ago: computed_di!("price_4y_ago"), + price_5y_ago: computed_di!("price_5y_ago"), + price_6y_ago: computed_di!("price_6y_ago"), + price_8y_ago: computed_di!("price_8y_ago"), + price_10y_ago: computed_di!("price_10y_ago"), + _1w_dca_stack: computed_di!("1w_dca_stack"), + _1m_dca_stack: computed_di!("1m_dca_stack"), + _3m_dca_stack: computed_di!("3m_dca_stack"), + _6m_dca_stack: computed_di!("6m_dca_stack"), + _1y_dca_stack: computed_di!("1y_dca_stack"), + _2y_dca_stack: computed_di!("2y_dca_stack"), + _3y_dca_stack: computed_di!("3y_dca_stack"), + _4y_dca_stack: computed_di!("4y_dca_stack"), + _5y_dca_stack: computed_di!("5y_dca_stack"), + _6y_dca_stack: computed_di!("6y_dca_stack"), + _8y_dca_stack: computed_di!("8y_dca_stack"), + _10y_dca_stack: computed_di!("10y_dca_stack"), + + dca_class_2025_stack: computed_di!("dca_class_2025_stack"), + dca_class_2024_stack: computed_di!("dca_class_2024_stack"), + dca_class_2023_stack: computed_di!("dca_class_2023_stack"), + dca_class_2022_stack: computed_di!("dca_class_2022_stack"), + dca_class_2021_stack: computed_di!("dca_class_2021_stack"), + dca_class_2020_stack: computed_di!("dca_class_2020_stack"), + dca_class_2019_stack: computed_di!("dca_class_2019_stack"), + dca_class_2018_stack: computed_di!("dca_class_2018_stack"), + dca_class_2017_stack: computed_di!("dca_class_2017_stack"), + dca_class_2016_stack: computed_di!("dca_class_2016_stack"), + dca_class_2015_stack: computed_di!("dca_class_2015_stack"), + + dca_class_2025_avg_price: computed_di!("dca_class_2025_avg_price"), + dca_class_2024_avg_price: computed_di!("dca_class_2024_avg_price"), + dca_class_2023_avg_price: computed_di!("dca_class_2023_avg_price"), + dca_class_2022_avg_price: computed_di!("dca_class_2022_avg_price"), + dca_class_2021_avg_price: computed_di!("dca_class_2021_avg_price"), + dca_class_2020_avg_price: computed_di!("dca_class_2020_avg_price"), + dca_class_2019_avg_price: computed_di!("dca_class_2019_avg_price"), + dca_class_2018_avg_price: computed_di!("dca_class_2018_avg_price"), + dca_class_2017_avg_price: computed_di!("dca_class_2017_avg_price"), + dca_class_2016_avg_price: computed_di!("dca_class_2016_avg_price"), + dca_class_2015_avg_price: computed_di!("dca_class_2015_avg_price"), + + dca_class_2025_returns: computed_di!("dca_class_2025_returns"), + dca_class_2024_returns: computed_di!("dca_class_2024_returns"), + dca_class_2023_returns: computed_di!("dca_class_2023_returns"), + dca_class_2022_returns: computed_di!("dca_class_2022_returns"), + dca_class_2021_returns: computed_di!("dca_class_2021_returns"), + dca_class_2020_returns: computed_di!("dca_class_2020_returns"), + dca_class_2019_returns: computed_di!("dca_class_2019_returns"), + dca_class_2018_returns: computed_di!("dca_class_2018_returns"), + dca_class_2017_returns: computed_di!("dca_class_2017_returns"), + dca_class_2016_returns: computed_di!("dca_class_2016_returns"), + dca_class_2015_returns: computed_di!("dca_class_2015_returns"), + + indexes_to_price_200d_sma_x2_4: computed_di!("price_200d_sma_x2_4"), + indexes_to_price_200d_sma_x0_8: computed_di!("price_200d_sma_x0_8"), + dateindex_to_price_true_range: eager_di!("price_true_range", v0), + dateindex_to_price_true_range_2w_sum: eager_di!("price_true_range_2w_sum", v0), + indexes_to_price_1w_min: computed_di!("price_1w_min", v1), + indexes_to_price_1w_max: computed_di!("price_1w_max", v1), + indexes_to_price_2w_min: computed_di!("price_2w_min", v1), + indexes_to_price_2w_max: computed_di!("price_2w_max", v1), + indexes_to_price_1m_min: computed_di!("price_1m_min", v1), + indexes_to_price_1m_max: computed_di!("price_1m_max", v1), + indexes_to_price_1y_min: computed_di!("price_1y_min", v1), + indexes_to_price_1y_max: computed_di!("price_1y_max", v1), + indexes_to_price_2w_choppiness_index: computed_di!("price_2w_choppiness_index", v1), + db, + }; + + this.db.retain_regions( + this.iter_any_exportable() + .flat_map(|v| v.region_names()) + .collect(), + )?; + + this.db.compact()?; + + Ok(this) + } +} diff --git a/crates/brk_computer/src/market/mod.rs b/crates/brk_computer/src/market/mod.rs new file mode 100644 index 000000000..4878c6936 --- /dev/null +++ b/crates/brk_computer/src/market/mod.rs @@ -0,0 +1,192 @@ +mod compute; +mod import; + +use brk_traversable::Traversable; +use brk_types::{DateIndex, Dollars, Height, Sats, StoredF32, StoredU16}; +use vecdb::{Database, EagerVec, PcoVec}; + +use crate::grouped::{ + ComputedRatioVecsFromDateIndex, ComputedStandardDeviationVecsFromDateIndex, + ComputedVecsFromDateIndex, +}; + +#[derive(Clone, Traversable)] +pub struct Vecs { + pub(crate) db: Database, + + pub height_to_price_ath: EagerVec>, + pub height_to_price_drawdown: EagerVec>, + pub indexes_to_price_ath: ComputedVecsFromDateIndex, + pub indexes_to_price_drawdown: ComputedVecsFromDateIndex, + pub indexes_to_days_since_price_ath: ComputedVecsFromDateIndex, + pub indexes_to_max_days_between_price_aths: ComputedVecsFromDateIndex, + pub indexes_to_max_years_between_price_aths: ComputedVecsFromDateIndex, + + pub indexes_to_1d_returns_1w_sd: ComputedStandardDeviationVecsFromDateIndex, + pub indexes_to_1d_returns_1m_sd: ComputedStandardDeviationVecsFromDateIndex, + pub indexes_to_1d_returns_1y_sd: ComputedStandardDeviationVecsFromDateIndex, + pub indexes_to_price_1w_volatility: ComputedVecsFromDateIndex, + pub indexes_to_price_1m_volatility: ComputedVecsFromDateIndex, + pub indexes_to_price_1y_volatility: ComputedVecsFromDateIndex, + + pub indexes_to_price_1w_min: ComputedVecsFromDateIndex, + pub indexes_to_price_1w_max: ComputedVecsFromDateIndex, + pub indexes_to_price_2w_min: ComputedVecsFromDateIndex, + pub indexes_to_price_2w_max: ComputedVecsFromDateIndex, + pub indexes_to_price_1m_min: ComputedVecsFromDateIndex, + pub indexes_to_price_1m_max: ComputedVecsFromDateIndex, + pub indexes_to_price_1y_min: ComputedVecsFromDateIndex, + pub indexes_to_price_1y_max: ComputedVecsFromDateIndex, + + pub dateindex_to_price_true_range: EagerVec>, + pub dateindex_to_price_true_range_2w_sum: EagerVec>, + pub indexes_to_price_2w_choppiness_index: ComputedVecsFromDateIndex, + + pub indexes_to_price_1w_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_8d_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_13d_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_21d_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_1m_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_34d_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_55d_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_89d_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_144d_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_200d_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_1y_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_2y_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_200w_sma: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_4y_sma: ComputedRatioVecsFromDateIndex, + + pub indexes_to_price_1w_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_8d_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_13d_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_21d_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_1m_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_34d_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_55d_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_89d_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_144d_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_200d_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_1y_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_2y_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_200w_ema: ComputedRatioVecsFromDateIndex, + pub indexes_to_price_4y_ema: ComputedRatioVecsFromDateIndex, + + pub indexes_to_price_200d_sma_x2_4: ComputedVecsFromDateIndex, + pub indexes_to_price_200d_sma_x0_8: ComputedVecsFromDateIndex, + + pub price_1d_ago: ComputedVecsFromDateIndex, + pub price_1w_ago: ComputedVecsFromDateIndex, + pub price_1m_ago: ComputedVecsFromDateIndex, + pub price_3m_ago: ComputedVecsFromDateIndex, + pub price_6m_ago: ComputedVecsFromDateIndex, + pub price_1y_ago: ComputedVecsFromDateIndex, + pub price_2y_ago: ComputedVecsFromDateIndex, + pub price_3y_ago: ComputedVecsFromDateIndex, + pub price_4y_ago: ComputedVecsFromDateIndex, + pub price_5y_ago: ComputedVecsFromDateIndex, + pub price_6y_ago: ComputedVecsFromDateIndex, + pub price_8y_ago: ComputedVecsFromDateIndex, + pub price_10y_ago: ComputedVecsFromDateIndex, + + pub _1d_price_returns: ComputedVecsFromDateIndex, + pub _1w_price_returns: ComputedVecsFromDateIndex, + pub _1m_price_returns: ComputedVecsFromDateIndex, + pub _3m_price_returns: ComputedVecsFromDateIndex, + pub _6m_price_returns: ComputedVecsFromDateIndex, + pub _1y_price_returns: ComputedVecsFromDateIndex, + pub _2y_price_returns: ComputedVecsFromDateIndex, + pub _3y_price_returns: ComputedVecsFromDateIndex, + pub _4y_price_returns: ComputedVecsFromDateIndex, + pub _5y_price_returns: ComputedVecsFromDateIndex, + pub _6y_price_returns: ComputedVecsFromDateIndex, + pub _8y_price_returns: ComputedVecsFromDateIndex, + pub _10y_price_returns: ComputedVecsFromDateIndex, + pub _2y_cagr: ComputedVecsFromDateIndex, + pub _3y_cagr: ComputedVecsFromDateIndex, + pub _4y_cagr: ComputedVecsFromDateIndex, + pub _5y_cagr: ComputedVecsFromDateIndex, + pub _6y_cagr: ComputedVecsFromDateIndex, + pub _8y_cagr: ComputedVecsFromDateIndex, + pub _10y_cagr: ComputedVecsFromDateIndex, + + pub _1w_dca_stack: ComputedVecsFromDateIndex, + pub _1m_dca_stack: ComputedVecsFromDateIndex, + pub _3m_dca_stack: ComputedVecsFromDateIndex, + pub _6m_dca_stack: ComputedVecsFromDateIndex, + pub _1y_dca_stack: ComputedVecsFromDateIndex, + pub _2y_dca_stack: ComputedVecsFromDateIndex, + pub _3y_dca_stack: ComputedVecsFromDateIndex, + pub _4y_dca_stack: ComputedVecsFromDateIndex, + pub _5y_dca_stack: ComputedVecsFromDateIndex, + pub _6y_dca_stack: ComputedVecsFromDateIndex, + pub _8y_dca_stack: ComputedVecsFromDateIndex, + pub _10y_dca_stack: ComputedVecsFromDateIndex, + pub _1w_dca_avg_price: ComputedVecsFromDateIndex, + pub _1m_dca_avg_price: ComputedVecsFromDateIndex, + pub _3m_dca_avg_price: ComputedVecsFromDateIndex, + pub _6m_dca_avg_price: ComputedVecsFromDateIndex, + pub _1y_dca_avg_price: ComputedVecsFromDateIndex, + pub _2y_dca_avg_price: ComputedVecsFromDateIndex, + pub _3y_dca_avg_price: ComputedVecsFromDateIndex, + pub _4y_dca_avg_price: ComputedVecsFromDateIndex, + pub _5y_dca_avg_price: ComputedVecsFromDateIndex, + pub _6y_dca_avg_price: ComputedVecsFromDateIndex, + pub _8y_dca_avg_price: ComputedVecsFromDateIndex, + pub _10y_dca_avg_price: ComputedVecsFromDateIndex, + pub _1w_dca_returns: ComputedVecsFromDateIndex, + pub _1m_dca_returns: ComputedVecsFromDateIndex, + pub _3m_dca_returns: ComputedVecsFromDateIndex, + pub _6m_dca_returns: ComputedVecsFromDateIndex, + pub _1y_dca_returns: ComputedVecsFromDateIndex, + pub _2y_dca_returns: ComputedVecsFromDateIndex, + pub _3y_dca_returns: ComputedVecsFromDateIndex, + pub _4y_dca_returns: ComputedVecsFromDateIndex, + pub _5y_dca_returns: ComputedVecsFromDateIndex, + pub _6y_dca_returns: ComputedVecsFromDateIndex, + pub _8y_dca_returns: ComputedVecsFromDateIndex, + pub _10y_dca_returns: ComputedVecsFromDateIndex, + pub _2y_dca_cagr: ComputedVecsFromDateIndex, + pub _3y_dca_cagr: ComputedVecsFromDateIndex, + pub _4y_dca_cagr: ComputedVecsFromDateIndex, + pub _5y_dca_cagr: ComputedVecsFromDateIndex, + pub _6y_dca_cagr: ComputedVecsFromDateIndex, + pub _8y_dca_cagr: ComputedVecsFromDateIndex, + pub _10y_dca_cagr: ComputedVecsFromDateIndex, + + pub dca_class_2025_stack: ComputedVecsFromDateIndex, + pub dca_class_2024_stack: ComputedVecsFromDateIndex, + pub dca_class_2023_stack: ComputedVecsFromDateIndex, + pub dca_class_2022_stack: ComputedVecsFromDateIndex, + pub dca_class_2021_stack: ComputedVecsFromDateIndex, + pub dca_class_2020_stack: ComputedVecsFromDateIndex, + pub dca_class_2019_stack: ComputedVecsFromDateIndex, + pub dca_class_2018_stack: ComputedVecsFromDateIndex, + pub dca_class_2017_stack: ComputedVecsFromDateIndex, + pub dca_class_2016_stack: ComputedVecsFromDateIndex, + pub dca_class_2015_stack: ComputedVecsFromDateIndex, + + pub dca_class_2025_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2024_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2023_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2022_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2021_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2020_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2019_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2018_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2017_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2016_avg_price: ComputedVecsFromDateIndex, + pub dca_class_2015_avg_price: ComputedVecsFromDateIndex, + + pub dca_class_2025_returns: ComputedVecsFromDateIndex, + pub dca_class_2024_returns: ComputedVecsFromDateIndex, + pub dca_class_2023_returns: ComputedVecsFromDateIndex, + pub dca_class_2022_returns: ComputedVecsFromDateIndex, + pub dca_class_2021_returns: ComputedVecsFromDateIndex, + pub dca_class_2020_returns: ComputedVecsFromDateIndex, + pub dca_class_2019_returns: ComputedVecsFromDateIndex, + pub dca_class_2018_returns: ComputedVecsFromDateIndex, + pub dca_class_2017_returns: ComputedVecsFromDateIndex, + pub dca_class_2016_returns: ComputedVecsFromDateIndex, + pub dca_class_2015_returns: ComputedVecsFromDateIndex, +}