diff --git a/crates/brk_computer/src/vecs/market.rs b/crates/brk_computer/src/vecs/market.rs index dc2206f7a..bc2d539df 100644 --- a/crates/brk_computer/src/vecs/market.rs +++ b/crates/brk_computer/src/vecs/market.rs @@ -1,6 +1,6 @@ use std::{fs, path::Path, thread}; -use brk_core::{Dollars, Sats, StoredF32, StoredUsize}; +use brk_core::{Date, DateIndex, Dollars, Sats, StoredF32, StoredUsize}; use brk_exit::Exit; use brk_indexer::Indexer; use brk_vec::{AnyCollectableVec, Compressed, Computation, StoredIndex, VecIterator, Version}; @@ -13,7 +13,7 @@ use super::{ indexes, transactions, }; -const VERSION: Version = Version::new(10); +const VERSION: Version = Version::new(0); #[derive(Clone)] pub struct Vecs { @@ -116,6 +116,42 @@ pub struct Vecs { 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, } impl Vecs { @@ -795,6 +831,240 @@ impl Vecs { compressed, StorableVecGeneatorOptions::default().add_last(), )?, + + dca_class_2025_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2025_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2024_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2024_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2023_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2023_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2022_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2022_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2021_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2021_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2020_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2020_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2019_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2019_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2018_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2018_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2017_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2017_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2016_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2016_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2015_stack: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2015_stack", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + + dca_class_2025_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2025_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2024_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2024_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2023_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2023_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2022_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2022_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2021_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2021_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2020_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2020_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2019_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2019_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2018_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2018_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2017_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2017_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2016_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2016_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2015_avg_price: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2015_avg_price", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + + dca_class_2025_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2025_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2024_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2024_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2023_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2023_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2022_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2022_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2021_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2021_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2020_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2020_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2019_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2019_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2018_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2018_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2017_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2017_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2016_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2016_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + dca_class_2015_returns: ComputedVecsFromDateIndex::forced_import( + path, + "dca_class_2015_returns", + VERSION + Version::ZERO, + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, }) } @@ -1151,7 +1421,7 @@ impl Vecs { starting_indexes, exit, |v, _, _, starting_indexes, exit| { - v.compute_dca_stack( + v.compute_dca_stack_via_len( starting_indexes.dateindex, &fetched.timeindexes_to_close.dateindex, days, @@ -1166,7 +1436,7 @@ impl Vecs { starting_indexes, exit, |v, _, _, starting_indexes, exit| { - v.compute_dca_avg_price( + v.compute_dca_avg_price_via_len( starting_indexes.dateindex, &dca_stack.dateindex, days, @@ -1211,6 +1481,128 @@ impl Vecs { }, )?; + [ + ( + 2015, + &mut self.dca_class_2015_avg_price, + &mut self.dca_class_2015_returns, + &mut self.dca_class_2015_stack, + ), + ( + 2016, + &mut self.dca_class_2016_avg_price, + &mut self.dca_class_2016_returns, + &mut self.dca_class_2016_stack, + ), + ( + 2017, + &mut self.dca_class_2017_avg_price, + &mut self.dca_class_2017_returns, + &mut self.dca_class_2017_stack, + ), + ( + 2018, + &mut self.dca_class_2018_avg_price, + &mut self.dca_class_2018_returns, + &mut self.dca_class_2018_stack, + ), + ( + 2019, + &mut self.dca_class_2019_avg_price, + &mut self.dca_class_2019_returns, + &mut self.dca_class_2019_stack, + ), + ( + 2020, + &mut self.dca_class_2020_avg_price, + &mut self.dca_class_2020_returns, + &mut self.dca_class_2020_stack, + ), + ( + 2021, + &mut self.dca_class_2021_avg_price, + &mut self.dca_class_2021_returns, + &mut self.dca_class_2021_stack, + ), + ( + 2022, + &mut self.dca_class_2022_avg_price, + &mut self.dca_class_2022_returns, + &mut self.dca_class_2022_stack, + ), + ( + 2023, + &mut self.dca_class_2023_avg_price, + &mut self.dca_class_2023_returns, + &mut self.dca_class_2023_stack, + ), + ( + 2024, + &mut self.dca_class_2024_avg_price, + &mut self.dca_class_2024_returns, + &mut self.dca_class_2024_stack, + ), + ( + 2025, + &mut self.dca_class_2025_avg_price, + &mut self.dca_class_2025_returns, + &mut self.dca_class_2025_stack, + ), + ] + .into_iter() + .try_for_each( + |(year, avg_price, returns, stack)| -> color_eyre::Result<()> { + let dateindex = DateIndex::try_from(Date::new(year, 1, 1)).unwrap(); + + stack.compute( + indexer, + indexes, + starting_indexes, + exit, + |v, _, _, starting_indexes, exit| { + v.compute_dca_stack_via_from( + starting_indexes.dateindex, + &fetched.timeindexes_to_close.dateindex, + dateindex, + exit, + ) + }, + )?; + + avg_price.compute( + indexer, + indexes, + starting_indexes, + exit, + |v, _, _, starting_indexes, exit| { + v.compute_dca_avg_price_via_from( + starting_indexes.dateindex, + &stack.dateindex, + dateindex, + exit, + ) + }, + )?; + + returns.compute( + indexer, + indexes, + starting_indexes, + exit, + |v, _, _, starting_indexes, exit| { + v.compute_percentage_difference( + starting_indexes.dateindex, + &fetched.timeindexes_to_close.dateindex, + &avg_price.dateindex, + exit, + ) + }, + )?; + + Ok(()) + }, + )?; + thread::scope(|s| -> color_eyre::Result<()> { [ (&mut self.indexes_to_1w_sma, 7), @@ -1348,6 +1740,39 @@ impl Vecs { self._6y_dca_stack.vecs(), self._8y_dca_stack.vecs(), self._10y_dca_stack.vecs(), + self.dca_class_2025_stack.vecs(), + self.dca_class_2024_stack.vecs(), + self.dca_class_2023_stack.vecs(), + self.dca_class_2022_stack.vecs(), + self.dca_class_2021_stack.vecs(), + self.dca_class_2020_stack.vecs(), + self.dca_class_2019_stack.vecs(), + self.dca_class_2018_stack.vecs(), + self.dca_class_2017_stack.vecs(), + self.dca_class_2016_stack.vecs(), + self.dca_class_2015_stack.vecs(), + self.dca_class_2025_avg_price.vecs(), + self.dca_class_2024_avg_price.vecs(), + self.dca_class_2023_avg_price.vecs(), + self.dca_class_2022_avg_price.vecs(), + self.dca_class_2021_avg_price.vecs(), + self.dca_class_2020_avg_price.vecs(), + self.dca_class_2019_avg_price.vecs(), + self.dca_class_2018_avg_price.vecs(), + self.dca_class_2017_avg_price.vecs(), + self.dca_class_2016_avg_price.vecs(), + self.dca_class_2015_avg_price.vecs(), + self.dca_class_2025_returns.vecs(), + self.dca_class_2024_returns.vecs(), + self.dca_class_2023_returns.vecs(), + self.dca_class_2022_returns.vecs(), + self.dca_class_2021_returns.vecs(), + self.dca_class_2020_returns.vecs(), + self.dca_class_2019_returns.vecs(), + self.dca_class_2018_returns.vecs(), + self.dca_class_2017_returns.vecs(), + self.dca_class_2016_returns.vecs(), + self.dca_class_2015_returns.vecs(), ] .concat() } diff --git a/crates/brk_vec/src/variants/eager.rs b/crates/brk_vec/src/variants/eager.rs index 8eb130457..e60e01756 100644 --- a/crates/brk_vec/src/variants/eager.rs +++ b/crates/brk_vec/src/variants/eager.rs @@ -9,7 +9,7 @@ use std::{ }; use brk_core::{ - Bitcoin, CheckedSub, Close, DateIndex, Dollars, Height, Sats, StoredUsize, TxIndex, + Bitcoin, CheckedSub, Close, Date, DateIndex, Dollars, Height, Sats, StoredUsize, TxIndex, }; use brk_exit::Exit; use log::info; @@ -668,7 +668,7 @@ where } impl EagerVec { - pub fn compute_dca_stack( + pub fn compute_dca_stack_via_len( &mut self, max_from: DateIndex, closes: &impl AnyIterableVec>, @@ -676,7 +676,7 @@ impl EagerVec { exit: &Exit, ) -> Result<()> { self.validate_computed_version_or_reset_file( - Version::ZERO + self.inner.version() + closes.version(), + Version::new(5) + self.inner.version() + closes.version(), )?; let mut other_iter = closes.iter(); @@ -698,6 +698,7 @@ impl EagerVec { if price != Dollars::ZERO { stack = prev.unwrap() + Sats::from(Bitcoin::from(DCA_AMOUNT / price)); + if i_usize >= len { let prev_price = *other_iter.unwrap_get_inner_(i_usize - len); if prev_price != Dollars::ZERO { @@ -715,10 +716,49 @@ impl EagerVec { self.safe_flush(exit) } + + pub fn compute_dca_stack_via_from( + &mut self, + max_from: DateIndex, + closes: &impl AnyIterableVec>, + from: DateIndex, + exit: &Exit, + ) -> Result<()> { + self.validate_computed_version_or_reset_file( + Version::ZERO + self.inner.version() + closes.version(), + )?; + + let mut prev = None; + + let index = max_from.min(DateIndex::from(self.len())); + closes.iter_at(index).try_for_each(|(i, closes)| { + let price = *closes.into_inner(); + let i_usize = i.unwrap_to_usize(); + if prev.is_none() { + if i_usize == 0 { + prev.replace(Sats::ZERO); + } else { + prev.replace(self.into_iter().unwrap_get_inner_(i_usize - 1)); + } + } + + let mut stack = Sats::ZERO; + + if price != Dollars::ZERO && i >= from { + stack = prev.unwrap() + Sats::from(Bitcoin::from(DCA_AMOUNT / price)); + } + + prev.replace(stack); + + self.forced_push_at(i, stack, exit) + })?; + + self.safe_flush(exit) + } } impl EagerVec { - pub fn compute_dca_avg_price( + pub fn compute_dca_avg_price_via_len( &mut self, max_from: DateIndex, stacks: &impl AnyIterableVec, @@ -726,14 +766,51 @@ impl EagerVec { exit: &Exit, ) -> Result<()> { self.validate_computed_version_or_reset_file( - Version::ONE + self.inner.version() + stacks.version(), + Version::TWO + self.inner.version() + stacks.version(), )?; let index = max_from.min(DateIndex::from(self.len())); + let first_price_date = DateIndex::try_from(Date::new(2010, 8, 16)).unwrap(); + stacks.iter_at(index).try_for_each(|(i, stack)| { let stack = stack.into_inner(); - let avg_price = DCA_AMOUNT * len.min(i.unwrap_to_usize() + 1) / Bitcoin::from(stack); + let mut avg_price = Dollars::from(f64::NAN); + if i > first_price_date { + avg_price = DCA_AMOUNT + * len + .min(i.unwrap_to_usize() + 1) + .min(i.checked_sub(first_price_date).unwrap().unwrap_to_usize() + 1) + / Bitcoin::from(stack); + } + self.forced_push_at(i, avg_price, exit) + })?; + + self.safe_flush(exit) + } + + pub fn compute_dca_avg_price_via_from( + &mut self, + max_from: DateIndex, + stacks: &impl AnyIterableVec, + from: DateIndex, + exit: &Exit, + ) -> Result<()> { + self.validate_computed_version_or_reset_file( + Version::ZERO + self.inner.version() + stacks.version(), + )?; + + let index = max_from.min(DateIndex::from(self.len())); + + let from_usize = from.unwrap_to_usize(); + + stacks.iter_at(index).try_for_each(|(i, stack)| { + let stack = stack.into_inner(); + let mut avg_price = Dollars::from(f64::NAN); + if i >= from { + avg_price = + DCA_AMOUNT * (i.unwrap_to_usize() + 1 - from_usize) / Bitcoin::from(stack); + } self.forced_push_at(i, avg_price, exit) })?; diff --git a/websites/kibo.money/scripts/main.js b/websites/kibo.money/scripts/main.js index 0e411761b..737172d3c 100644 --- a/websites/kibo.money/scripts/main.js +++ b/websites/kibo.money/scripts/main.js @@ -1631,6 +1631,23 @@ function createColors(dark, elements) { _4y: purple, _10y: fuchsia, + 2015: pink, + 2016: red, + 2017: orange, + 2018: amber, + 2019: yellow, + 2020: lime, + 2021: green, + 2022: emerald, + 2023: teal, + 2024: cyan, + 2025: sky, + 2026: blue, + 2027: indigo, + 2028: violet, + 2029: purple, + 2030: fuchsia, + // r1d: pink, // r1w: red, // r1m: amber, diff --git a/websites/kibo.money/scripts/options.js b/websites/kibo.money/scripts/options.js index de753da51..c9dd5851d 100644 --- a/websites/kibo.money/scripts/options.js +++ b/websites/kibo.money/scripts/options.js @@ -194,6 +194,10 @@ function createPartialOptions(colors) { { name: "4 Years", key: "4y", days: 4 * 365 }, ]); + const dcaClasses = /** @type {const} */ ([ + 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, + ]); + /** * @param {Object} args * @param {ChartableVecId} args.key @@ -329,6 +333,506 @@ function createPartialOptions(colors) { name: "Price", title: "Bitcoin Price", }, + { + name: "Market", + tree: [ + { + name: "Capitalization", + title: "Market Capitalization", + bottom: [ + createBaseSeries({ + key: "marketcap", + name: "Capitalization", + }), + ], + }, + { + name: "All Time High", + tree: [ + { + name: "Value", + title: "All Time High", + top: [ + createBaseSeries({ + key: "ath", + name: "ath", + }), + ], + }, + { + name: "drawdown", + title: "All Time High Drawdown", + top: [ + createBaseSeries({ + key: "ath", + name: "ath", + }), + ], + bottom: [ + createBaseSeries({ + key: "drawdown", + name: "Drawdown", + color: colors.red, + }), + ], + }, + { + name: "days since", + title: "Number of days Since All Time High", + top: [ + createBaseSeries({ + key: "ath", + name: "ath", + }), + ], + bottom: [ + createBaseSeries({ + key: "days-since-ath", + name: "Days", + }), + ], + }, + { + name: "max between", + title: "Maximum time between All Time Highs", + top: [ + createBaseSeries({ + key: "ath", + name: "ath", + }), + ], + bottom: [ + createBaseSeries({ + key: "max-days-between-ath", + name: "Days", + }), + createBaseSeries({ + key: "max-years-between-ath", + name: "Years", + }), + ], + }, + ], + }, + { + name: "Average", + tree: [ + { + name: "Compare", + title: "Moving Averages", + top: averages.map(({ days, key, name }) => + createBaseSeries({ + key: `${key}-sma`, + name: key, + color: colors[`_${key}`], + }), + ), + }, + ...averages.map(({ key, name }) => ({ + name, + title: `${name} Market Price Moving Average`, + top: [ + createBaseSeries({ + key: `${key}-sma`, + name: "Average", + color: colors[`_${key}`], + }), + createBaseSeries({ + key: `${key}-sma-ratio-p1sd-as-price`, + name: "+1σ", + color: colors.orange, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p2sd-as-price`, + name: "+2σ", + color: colors.red, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p3sd-as-price`, + name: "+3σ", + color: colors.pink, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-m1sd-as-price`, + name: "−1σ", + color: colors.cyan, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-m2sd-as-price`, + name: "−2σ", + color: colors.blue, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-m3sd-as-price`, + name: "−3σ", + color: colors.violet, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p99-as-price`, + name: "p99", + color: colors.orange, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p99-5-as-price`, + name: "p99.5", + color: colors.red, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p99-9-as-price`, + name: "p99.9", + color: colors.pink, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p1-as-price`, + name: "p1", + color: colors.cyan, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p0-5-as-price`, + name: "p0.5", + color: colors.blue, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p0-1-as-price`, + name: "p0.1", + color: colors.violet, + defaultActive: false, + }), + ], + bottom: [ + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `${key}-sma-ratio`, + title: "Ratio", + type: "Baseline", + options: { + baseValue: { price: 1 }, + createPriceLine: { + value: 1, + }, + }, + }), + createBaseSeries({ + key: `${key}-sma-ratio-sma`, + name: "sma", + color: colors.yellow, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p1sd`, + name: "+1σ", + color: colors.orange, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p2sd`, + name: "+2σ", + color: colors.red, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p3sd`, + name: "+3σ", + color: colors.pink, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-m1sd`, + name: "−1σ", + color: colors.cyan, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-m2sd`, + name: "−2σ", + color: colors.blue, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-m3sd`, + name: "−3σ", + color: colors.violet, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p99`, + name: "p99", + color: colors.orange, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p99-5`, + name: "p99.5", + color: colors.red, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p99-9`, + name: "p99.9", + color: colors.pink, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p1`, + name: "p1", + color: colors.cyan, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p0-5`, + name: "p0.5", + color: colors.blue, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-p0-1`, + name: "p0.1", + color: colors.violet, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-1w-sma`, + name: "1w sma", + color: colors.fuchsia, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-1m-sma`, + name: "1m sma", + color: colors.pink, + defaultActive: false, + }), + createBaseSeries({ + key: `${key}-sma-ratio-1y-sma`, + name: "1y sma", + color: colors.rose, + defaultActive: false, + }), + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `${key}-sma-ratio-1y-sma-momentum-oscillator`, + title: "1Y Momentum", + type: "Baseline", + options: { + createPriceLine: { + value: 0, + }, + }, + }), + ], + })), + ], + }, + { + name: "Performance", + tree: /** @type {const} */ ([ + { name: "1 Day", key: "1d" }, + { name: "1 Week", key: "1w" }, + { name: "1 Month", key: "1m" }, + { name: "3 Month", key: "3m" }, + { name: "6 Month", key: "6m" }, + { name: "1 Year", key: "1y" }, + { name: "2 Year", key: "2y" }, + { name: "3 Year", key: "3y" }, + { name: "4 Year", key: "4y" }, + { name: "5 Year", key: "5y" }, + { name: "6 Year", key: "6y" }, + { name: "8 Year", key: "8y" }, + { name: "10 Year", key: "10y" }, + ]).map(({ name, key }) => ({ + name, + title: `${name} Performance`, + bottom: [ + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `${key}-returns`, + title: "Returns", + type: "Baseline", + options: { + createPriceLine: { + value: 0, + }, + }, + }), + ], + })), + }, + { + name: "DCA vs Lump sum", + tree: [ + .../** @type {const} */ ([ + { name: "1 Week", key: "1w" }, + { name: "1 Month", key: "1m" }, + { name: "3 Month", key: "3m" }, + { name: "6 Month", key: "6m" }, + { name: "1 Year", key: "1y" }, + ]).map( + ({ name, key }) => + /** @satisfies {PartialChartOption} */ ({ + name, + title: `${name} DCA vs Lump Sum Returns`, + top: [ + createBaseSeries({ + key: `${key}-dca-avg-price`, + name: `dca`, + color: colors.orange, + }), + createBaseSeries({ + key: `price-${key}-ago`, + name: `lump sum`, + color: colors.cyan, + }), + ], + bottom: [ + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `${key}-dca-returns`, + title: "dca", + type: "Baseline", + colors: [colors.yellow, colors.pink], + options: { + createPriceLine: { + value: 0, + }, + }, + }), + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `${key}-returns`, + title: "lump sum", + type: "Baseline", + options: { + createPriceLine: { + value: 0, + }, + }, + }), + ], + }), + ), + .../** @type {const} */ ([ + { name: "2 Year", key: "2y" }, + { name: "3 Year", key: "3y" }, + { name: "4 Year", key: "4y" }, + { name: "5 Year", key: "5y" }, + { name: "6 Year", key: "6y" }, + { name: "8 Year", key: "8y" }, + { name: "10 Year", key: "10y" }, + ]).map( + ({ name, key }) => + /** @satisfies {PartialChartOption} */ ({ + name, + title: `${name} DCA vs Lump Sum Returns`, + top: [ + createBaseSeries({ + key: `${key}-dca-avg-price`, + name: `dca avg. price`, + color: colors.orange, + }), + createBaseSeries({ + key: `price-${key}-ago`, + name: `lump sum price`, + color: colors.cyan, + }), + ], + bottom: [ + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `${key}-dca-returns`, + title: "dca", + type: "Baseline", + colors: [colors.yellow, colors.pink], + options: { + createPriceLine: { + value: 0, + }, + }, + }), + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `${key}-dca-cagr`, + title: "dca", + type: "Baseline", + colors: [colors.yellow, colors.pink], + options: { + createPriceLine: { + value: 0, + }, + }, + }), + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `${key}-returns`, + title: "lump sum", + type: "Baseline", + options: { + createPriceLine: { + value: 0, + }, + }, + }), + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `${key}-cagr`, + title: "lump sum", + type: "Baseline", + options: { + createPriceLine: { + value: 0, + }, + }, + }), + ], + }), + ), + ], + }, + { + name: "DCA Class", + tree: [ + { + name: "Compare", + title: "DCA Classes", + top: dcaClasses.map((year) => + createBaseSeries({ + key: `dca-class-${year}-avg-price`, + name: `${year}`, + color: colors[year], + }), + ), + }, + ...dcaClasses.map( + (year) => + /** @satisfies {PartialChartOption} */ ({ + name: `${year}`, + title: `DCA Since ${year}`, + top: [ + createBaseSeries({ + key: `dca-class-${year}-avg-price`, + name: `avg. price`, + color: colors[year], + }), + ], + bottom: [ + /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ + key: `dca-class-${year}-returns`, + title: "dca", + type: "Baseline", + options: { + createPriceLine: { + value: 0, + }, + }, + }), + ], + }), + ), + ], + }, + ], + }, { name: "Block", tree: [ @@ -403,61 +907,6 @@ function createPartialOptions(colors) { name: "Count", }), }, - { - name: "Subsidy", - title: "Subsidy", - bottom: [ - ...createBaseAverageSumTotalMinMaxPercentilesSeries({ - key: "subsidy", - name: "Subsidy", - }), - ...createBaseAverageSumTotalMinMaxPercentilesSeries({ - key: "subsidy-in-btc", - name: "Subsidy", - }), - ...createBaseAverageSumTotalMinMaxPercentilesSeries({ - key: "subsidy-in-usd", - name: "Subsidy", - }), - ], - }, - { - name: "Coinbase", - title: "Coinbase", - bottom: [ - ...createBaseAverageSumTotalMinMaxPercentilesSeries({ - key: "coinbase", - name: "Coinbase", - }), - ...createBaseAverageSumTotalMinMaxPercentilesSeries({ - key: "coinbase-in-btc", - name: "Coinbase", - }), - ...createBaseAverageSumTotalMinMaxPercentilesSeries({ - key: "coinbase-in-usd", - name: "Coinbase", - }), - ], - }, - { - name: "Fee", - title: "Transaction Fee", - bottom: [ - ...createAverageSumTotalMinMaxPercentilesSeries("fee"), - ...createAverageSumTotalMinMaxPercentilesSeries("fee-in-btc"), - ...createAverageSumTotalMinMaxPercentilesSeries("fee-in-usd"), - ], - }, - { - name: "Feerate", - title: "Transaction Fee Rate", - bottom: [ - createAverageSeries({ concat: "feerate" }), - ...createMinMaxPercentilesSeries({ - concat: "feerate", - }), - ], - }, { name: "Weight", title: "Transaction Weight", @@ -775,7 +1224,62 @@ function createPartialOptions(colors) { bottom: [ createBaseSeries({ key: "total-subsidy-in-btc", - name: "Supply", + name: "Mined", + }), + ], + }, + { + name: "Coinbase", + title: "Coinbase", + bottom: [ + ...createBaseAverageSumTotalMinMaxPercentilesSeries({ + key: "coinbase", + name: "Coinbase", + }), + ...createBaseAverageSumTotalMinMaxPercentilesSeries({ + key: "coinbase-in-btc", + name: "Coinbase", + }), + ...createBaseAverageSumTotalMinMaxPercentilesSeries({ + key: "coinbase-in-usd", + name: "Coinbase", + }), + ], + }, + { + name: "Subsidy", + title: "Subsidy", + bottom: [ + ...createBaseAverageSumTotalMinMaxPercentilesSeries({ + key: "subsidy", + name: "Subsidy", + }), + ...createBaseAverageSumTotalMinMaxPercentilesSeries({ + key: "subsidy-in-btc", + name: "Subsidy", + }), + ...createBaseAverageSumTotalMinMaxPercentilesSeries({ + key: "subsidy-in-usd", + name: "Subsidy", + }), + ], + }, + { + name: "Fee", + title: "Transaction Fee", + bottom: [ + ...createAverageSumTotalMinMaxPercentilesSeries("fee"), + ...createAverageSumTotalMinMaxPercentilesSeries("fee-in-btc"), + ...createAverageSumTotalMinMaxPercentilesSeries("fee-in-usd"), + ], + }, + { + name: "Feerate", + title: "Transaction Fee Rate", + bottom: [ + createAverageSeries({ concat: "feerate" }), + ...createMinMaxPercentilesSeries({ + concat: "feerate", }), ], }, @@ -811,453 +1315,6 @@ function createPartialOptions(colors) { }, ], }, - { - name: "Market", - tree: [ - { - name: "Capitalization", - title: "Market Capitalization", - bottom: [ - createBaseSeries({ - key: "marketcap", - name: "Capitalization", - }), - ], - }, - { - name: "All Time High", - tree: [ - { - name: "Value", - title: "All Time High", - top: [ - createBaseSeries({ - key: "ath", - name: "ath", - }), - ], - }, - { - name: "drawdown", - title: "All Time High Drawdown", - top: [ - createBaseSeries({ - key: "ath", - name: "ath", - }), - ], - bottom: [ - createBaseSeries({ - key: "drawdown", - name: "Drawdown", - color: colors.red, - }), - ], - }, - { - name: "days since", - title: "Number of days Since All Time High", - top: [ - createBaseSeries({ - key: "ath", - name: "ath", - }), - ], - bottom: [ - createBaseSeries({ - key: "days-since-ath", - name: "Days", - }), - ], - }, - { - name: "max between", - title: "Maximum time between All Time Highs", - top: [ - createBaseSeries({ - key: "ath", - name: "ath", - }), - ], - bottom: [ - createBaseSeries({ - key: "max-days-between-ath", - name: "Days", - }), - createBaseSeries({ - key: "max-years-between-ath", - name: "Years", - }), - ], - }, - ], - }, - { - name: "Average", - tree: [ - { - name: "Compare", - title: "Moving Averages", - top: averages.map(({ days, key, name }) => - createBaseSeries({ - key: `${key}-sma`, - name: key, - color: colors[`_${key}`], - }), - ), - }, - ...averages.map(({ key, name }) => ({ - name, - title: `${name} Market Price Moving Average`, - top: [ - createBaseSeries({ - key: `${key}-sma`, - name: "Average", - color: colors[`_${key}`], - }), - createBaseSeries({ - key: `${key}-sma-ratio-p1sd-as-price`, - name: "+1σ", - color: colors.orange, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p2sd-as-price`, - name: "+2σ", - color: colors.red, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p3sd-as-price`, - name: "+3σ", - color: colors.pink, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-m1sd-as-price`, - name: "−1σ", - color: colors.cyan, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-m2sd-as-price`, - name: "−2σ", - color: colors.blue, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-m3sd-as-price`, - name: "−3σ", - color: colors.violet, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p99-as-price`, - name: "p99", - color: colors.orange, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p99-5-as-price`, - name: "p99.5", - color: colors.red, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p99-9-as-price`, - name: "p99.9", - color: colors.pink, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p1-as-price`, - name: "p1", - color: colors.cyan, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p0-5-as-price`, - name: "p0.5", - color: colors.blue, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p0-1-as-price`, - name: "p0.1", - color: colors.violet, - defaultActive: false, - }), - ], - bottom: [ - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - key: `${key}-sma-ratio`, - title: "Ratio", - type: "Baseline", - options: { - baseValue: { price: 1 }, - createPriceLine: { - value: 1, - }, - }, - }), - createBaseSeries({ - key: `${key}-sma-ratio-sma`, - name: "sma", - color: colors.yellow, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p1sd`, - name: "+1σ", - color: colors.orange, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p2sd`, - name: "+2σ", - color: colors.red, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p3sd`, - name: "+3σ", - color: colors.pink, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-m1sd`, - name: "−1σ", - color: colors.cyan, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-m2sd`, - name: "−2σ", - color: colors.blue, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-m3sd`, - name: "−3σ", - color: colors.violet, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p99`, - name: "p99", - color: colors.orange, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p99-5`, - name: "p99.5", - color: colors.red, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p99-9`, - name: "p99.9", - color: colors.pink, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p1`, - name: "p1", - color: colors.cyan, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p0-5`, - name: "p0.5", - color: colors.blue, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-p0-1`, - name: "p0.1", - color: colors.violet, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-1w-sma`, - name: "1w sma", - color: colors.fuchsia, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-1m-sma`, - name: "1m sma", - color: colors.pink, - defaultActive: false, - }), - createBaseSeries({ - key: `${key}-sma-ratio-1y-sma`, - name: "1y sma", - color: colors.rose, - defaultActive: false, - }), - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - key: `${key}-sma-ratio-1y-sma-momentum-oscillator`, - title: "1Y Momentum", - type: "Baseline", - options: { - createPriceLine: { - value: 0, - }, - }, - }), - ], - })), - ], - }, - { - name: "Returns", - tree: [ - { - name: "1 Day", - title: `1 Day Returns`, - top: [ - createBaseSeries({ - key: `price-1d-ago`, - name: `Price 1d ago`, - }), - ], - bottom: [ - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - key: `1d-returns`, - title: "1d", - type: "Baseline", - options: { - createPriceLine: { - value: 0, - }, - }, - }), - ], - }, - .../** @type {const} */ ([ - { name: "1 Week", key: "1w" }, - { name: "1 Month", key: "1m" }, - { name: "3 Months", key: "3m" }, - { name: "6 Months", key: "6m" }, - { name: "1 Year", key: "1y" }, - ]).map( - ({ name, key }) => - /** @satisfies {PartialChartOption} */ ({ - name, - title: `${name} Returns`, - top: [ - createBaseSeries({ - key: `price-${key}-ago`, - name: `lump sum`, - color: colors.cyan, - }), - createBaseSeries({ - key: `${key}-dca-avg-price`, - name: `dca`, - color: colors.orange, - }), - ], - bottom: [ - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - key: `${key}-returns`, - title: "lump sum", - type: "Baseline", - options: { - createPriceLine: { - value: 0, - }, - }, - }), - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - key: `${key}-dca-returns`, - title: "dca", - type: "Baseline", - colors: [colors.yellow, colors.pink], - options: { - createPriceLine: { - value: 0, - }, - }, - }), - ], - }), - ), - .../** @type {const} */ ([ - { name: "2 Year", key: "2y" }, - { name: "3 Year", key: "3y" }, - { name: "4 Year", key: "4y" }, - { name: "5 Year", key: "5y" }, - { name: "6 Year", key: "6y" }, - { name: "8 Year", key: "8y" }, - { name: "10 Year", key: "10y" }, - ]).map( - ({ name, key }) => - /** @satisfies {PartialChartOption} */ ({ - name, - title: `${name} Returns`, - top: [ - createBaseSeries({ - key: `price-${key}-ago`, - name: `lump sum price`, - color: colors.cyan, - }), - createBaseSeries({ - key: `${key}-dca-avg-price`, - name: `dca avg. price`, - color: colors.orange, - }), - ], - bottom: [ - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - key: `${key}-returns`, - title: "lump sum", - type: "Baseline", - options: { - createPriceLine: { - value: 0, - }, - }, - }), - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - key: `${key}-cagr`, - title: "lump sum", - type: "Baseline", - options: { - createPriceLine: { - value: 0, - }, - }, - }), - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - key: `${key}-dca-returns`, - title: "dca", - type: "Baseline", - colors: [colors.yellow, colors.pink], - options: { - createPriceLine: { - value: 0, - }, - }, - }), - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - key: `${key}-dca-cagr`, - title: "dca", - type: "Baseline", - colors: [colors.yellow, colors.pink], - options: { - createPriceLine: { - value: 0, - }, - }, - }), - ], - }), - ), - ], - }, - ], - }, ], }, { diff --git a/websites/kibo.money/scripts/vecid-to-indexes.js b/websites/kibo.money/scripts/vecid-to-indexes.js index 23fff4d4c..ed6ceda57 100644 --- a/websites/kibo.money/scripts/vecid-to-indexes.js +++ b/websites/kibo.money/scripts/vecid-to-indexes.js @@ -593,6 +593,39 @@ export function createVecIdToIndexes() { "dateindex": [DateIndex, Height], "dateindex-count": [MonthIndex, WeekIndex], "days-since-ath": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2015-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2015-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2015-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2016-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2016-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2016-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2017-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2017-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2017-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2018-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2018-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2018-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2019-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2019-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2019-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2020-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2020-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2020-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2021-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2021-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2021-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2022-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2022-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2022-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2023-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2023-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2023-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2024-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2024-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2024-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2025-avg-price": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2025-returns": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], + "dca-class-2025-stack": [DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex], "decadeindex": [DecadeIndex, YearIndex], "difficulty": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex], "difficultyepoch": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],