diff --git a/crates/brk_computer/src/storage/vecs/blocks.rs b/crates/brk_computer/src/storage/vecs/blocks.rs index a96c91475..7e99ee33a 100644 --- a/crates/brk_computer/src/storage/vecs/blocks.rs +++ b/crates/brk_computer/src/storage/vecs/blocks.rs @@ -7,13 +7,13 @@ use brk_vec::{AnyStorableVec, Compressed, Version}; use super::{ Indexes, StorableVec, indexes, - stats::{StorableVecGeneatorByIndex, StorableVecGeneatorOptions}, + stats::{StorableVecGeneatorOptions, StorableVecsStatsFromHeight}, }; #[derive(Clone)] pub struct Vecs { pub height_to_block_interval: StorableVec, - pub indexes_to_block_interval_stats: StorableVecGeneatorByIndex, + pub indexes_to_block_interval_stats: StorableVecsStatsFromHeight, pub dateindex_to_block_count: StorableVec, pub dateindex_to_total_block_count: StorableVec, } @@ -28,7 +28,7 @@ impl Vecs { Version::from(1), compressed, )?, - indexes_to_block_interval_stats: StorableVecGeneatorByIndex::forced_import( + indexes_to_block_interval_stats: StorableVecsStatsFromHeight::forced_import( &path.join("block_interval"), compressed, StorableVecGeneatorOptions::default() @@ -64,12 +64,10 @@ impl Vecs { |(height, timestamp, _, height_to_timestamp)| { let interval = height.decremented().map_or(Timestamp::ZERO, |prev_h| { let prev_timestamp = *height_to_timestamp.get(prev_h).unwrap().unwrap(); - dbg!((timestamp, prev_timestamp)); timestamp .checked_sub(prev_timestamp) .unwrap_or(Timestamp::ZERO) }); - dbg!((height, interval)); (height, interval) }, exit, diff --git a/crates/brk_computer/src/storage/vecs/marketprice.rs b/crates/brk_computer/src/storage/vecs/marketprice.rs index 47a101abb..a7ad2e19e 100644 --- a/crates/brk_computer/src/storage/vecs/marketprice.rs +++ b/crates/brk_computer/src/storage/vecs/marketprice.rs @@ -1,39 +1,61 @@ use std::{fs, path::Path}; use brk_core::{ - Cents, Close, Dateindex, Dollars, Height, High, Low, OHLCCents, OHLCDollars, Open, Sats, + Cents, Close, Dateindex, Decadeindex, Difficultyepoch, Dollars, Height, High, Low, Monthindex, + OHLCCents, OHLCDollars, Open, Sats, Weekindex, Yearindex, }; use brk_exit::Exit; use brk_fetcher::Fetcher; use brk_indexer::Indexer; use brk_vec::{AnyStorableVec, Compressed, Version}; -use super::{Indexes, StorableVec, indexes}; +use super::{ + Indexes, StorableVec, indexes, + stats::{ + StorableVecGeneatorOptions, StorableVecsStatsFromDate, StorableVecsStatsFromHeightStrict, + }, +}; #[derive(Clone)] pub struct Vecs { - pub dateindex_to_ohlc_in_cents: StorableVec, - pub dateindex_to_ohlc: StorableVec, - pub dateindex_to_close_in_cents: StorableVec>, pub dateindex_to_close: StorableVec>, - pub dateindex_to_high_in_cents: StorableVec>, + pub dateindex_to_close_in_cents: StorableVec>, pub dateindex_to_high: StorableVec>, - pub dateindex_to_low_in_cents: StorableVec>, + pub dateindex_to_high_in_cents: StorableVec>, pub dateindex_to_low: StorableVec>, - pub dateindex_to_open_in_cents: StorableVec>, + pub dateindex_to_low_in_cents: StorableVec>, + pub dateindex_to_ohlc: StorableVec, + pub dateindex_to_ohlc_in_cents: StorableVec, pub dateindex_to_open: StorableVec>, + pub dateindex_to_open_in_cents: StorableVec>, pub dateindex_to_sats_per_dollar: StorableVec>, - pub height_to_ohlc_in_cents: StorableVec, - pub height_to_ohlc: StorableVec, - pub height_to_close_in_cents: StorableVec>, pub height_to_close: StorableVec>, - pub height_to_high_in_cents: StorableVec>, + pub height_to_close_in_cents: StorableVec>, pub height_to_high: StorableVec>, - pub height_to_low_in_cents: StorableVec>, + pub height_to_high_in_cents: StorableVec>, pub height_to_low: StorableVec>, - pub height_to_open_in_cents: StorableVec>, + pub height_to_low_in_cents: StorableVec>, + pub height_to_ohlc: StorableVec, + pub height_to_ohlc_in_cents: StorableVec, pub height_to_open: StorableVec>, + pub height_to_open_in_cents: StorableVec>, pub height_to_sats_per_dollar: StorableVec>, + pub timeindexes_to_close: StorableVecsStatsFromDate>, + pub timeindexes_to_high: StorableVecsStatsFromDate>, + pub timeindexes_to_low: StorableVecsStatsFromDate>, + pub timeindexes_to_open: StorableVecsStatsFromDate>, + pub timeindexes_to_sats_per_dollar: StorableVecsStatsFromDate>, + pub chainindexes_to_close: StorableVecsStatsFromHeightStrict>, + pub chainindexes_to_high: StorableVecsStatsFromHeightStrict>, + pub chainindexes_to_low: StorableVecsStatsFromHeightStrict>, + pub chainindexes_to_open: StorableVecsStatsFromHeightStrict>, + pub chainindexes_to_sats_per_dollar: StorableVecsStatsFromHeightStrict>, + pub weekindex_to_ohlc: StorableVec, + pub difficultyepoch_to_ohlc: StorableVec, + pub monthindex_to_ohlc: StorableVec, + pub yearindex_to_ohlc: StorableVec, + // pub halvingepoch_to_ohlc: StorableVec, + pub decadeindex_to_ohlc: StorableVec, } impl Vecs { @@ -151,6 +173,82 @@ impl Vecs { Version::from(1), compressed, )?, + timeindexes_to_open: StorableVecsStatsFromDate::forced_import( + &path.join("open"), + compressed, + StorableVecGeneatorOptions::default().add_first(), + )?, + timeindexes_to_high: StorableVecsStatsFromDate::forced_import( + &path.join("high"), + compressed, + StorableVecGeneatorOptions::default().add_max(), + )?, + timeindexes_to_low: StorableVecsStatsFromDate::forced_import( + &path.join("low"), + compressed, + StorableVecGeneatorOptions::default().add_min(), + )?, + timeindexes_to_close: StorableVecsStatsFromDate::forced_import( + &path.join("close"), + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + timeindexes_to_sats_per_dollar: StorableVecsStatsFromDate::forced_import( + &path.join("sats_per_dollar"), + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + chainindexes_to_open: StorableVecsStatsFromHeightStrict::forced_import( + &path.join("open"), + compressed, + StorableVecGeneatorOptions::default().add_first(), + )?, + chainindexes_to_high: StorableVecsStatsFromHeightStrict::forced_import( + &path.join("high"), + compressed, + StorableVecGeneatorOptions::default().add_max(), + )?, + chainindexes_to_low: StorableVecsStatsFromHeightStrict::forced_import( + &path.join("low"), + compressed, + StorableVecGeneatorOptions::default().add_min(), + )?, + chainindexes_to_close: StorableVecsStatsFromHeightStrict::forced_import( + &path.join("close"), + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + chainindexes_to_sats_per_dollar: StorableVecsStatsFromHeightStrict::forced_import( + &path.join("sats_per_dollar"), + compressed, + StorableVecGeneatorOptions::default().add_last(), + )?, + weekindex_to_ohlc: StorableVec::forced_import( + &path.join("weekindex_to_ohlc"), + Version::from(1), + compressed, + )?, + difficultyepoch_to_ohlc: StorableVec::forced_import( + &path.join("difficultyepoch_to_ohlc"), + Version::from(1), + compressed, + )?, + monthindex_to_ohlc: StorableVec::forced_import( + &path.join("monthindex_to_ohlc"), + Version::from(1), + compressed, + )?, + yearindex_to_ohlc: StorableVec::forced_import( + &path.join("yearindex_to_ohlc"), + Version::from(1), + compressed, + )?, + // halvingepoch_to_ohlc: StorableVec::forced_import(&path.join("halvingepoch_to_ohlc"), Version::from(1), compressed)?, + decadeindex_to_ohlc: StorableVec::forced_import( + &path.join("decadeindex_to_ohlc"), + Version::from(1), + compressed, + )?, }) } @@ -331,33 +429,340 @@ impl Vecs { exit, )?; + self.timeindexes_to_close.compute( + &mut self.dateindex_to_close, + indexes, + starting_indexes, + exit, + )?; + + self.timeindexes_to_high.compute( + &mut self.dateindex_to_high, + indexes, + starting_indexes, + exit, + )?; + + self.timeindexes_to_low.compute( + &mut self.dateindex_to_low, + indexes, + starting_indexes, + exit, + )?; + + self.timeindexes_to_open.compute( + &mut self.dateindex_to_open, + indexes, + starting_indexes, + exit, + )?; + + self.chainindexes_to_close.compute( + &mut self.height_to_close, + indexes, + starting_indexes, + exit, + )?; + + self.chainindexes_to_high.compute( + &mut self.height_to_high, + indexes, + starting_indexes, + exit, + )?; + + self.chainindexes_to_low.compute( + &mut self.height_to_low, + indexes, + starting_indexes, + exit, + )?; + + self.chainindexes_to_open.compute( + &mut self.height_to_open, + indexes, + starting_indexes, + exit, + )?; + + self.weekindex_to_ohlc.compute_transform( + starting_indexes.weekindex, + self.timeindexes_to_close + .weekindex + .last + .as_mut() + .unwrap() + .mut_vec(), + |(i, close, ..)| { + ( + i, + OHLCDollars { + open: *self + .timeindexes_to_open + .weekindex + .first + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + high: *self + .timeindexes_to_high + .weekindex + .max + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + low: *self + .timeindexes_to_low + .weekindex + .min + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + close, + }, + ) + }, + exit, + )?; + + self.difficultyepoch_to_ohlc.compute_transform( + starting_indexes.difficultyepoch, + self.chainindexes_to_close + .difficultyepoch + .last + .as_mut() + .unwrap() + .mut_vec(), + |(i, close, ..)| { + ( + i, + OHLCDollars { + open: *self + .chainindexes_to_open + .difficultyepoch + .first + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + high: *self + .chainindexes_to_high + .difficultyepoch + .max + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + low: *self + .chainindexes_to_low + .difficultyepoch + .min + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + close, + }, + ) + }, + exit, + )?; + + self.monthindex_to_ohlc.compute_transform( + starting_indexes.monthindex, + self.timeindexes_to_close + .monthindex + .last + .as_mut() + .unwrap() + .mut_vec(), + |(i, close, ..)| { + ( + i, + OHLCDollars { + open: *self + .timeindexes_to_open + .monthindex + .first + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + high: *self + .timeindexes_to_high + .monthindex + .max + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + low: *self + .timeindexes_to_low + .monthindex + .min + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + close, + }, + ) + }, + exit, + )?; + + self.yearindex_to_ohlc.compute_transform( + starting_indexes.yearindex, + self.timeindexes_to_close + .yearindex + .last + .as_mut() + .unwrap() + .mut_vec(), + |(i, close, ..)| { + ( + i, + OHLCDollars { + open: *self + .timeindexes_to_open + .yearindex + .first + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + high: *self + .timeindexes_to_high + .yearindex + .max + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + low: *self + .timeindexes_to_low + .yearindex + .min + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + close, + }, + ) + }, + exit, + )?; + + // self.halvingepoch_to_ohlc + // .compute_transform(starting_indexes.halvingepoch, other, t, exit)?; + + self.decadeindex_to_ohlc.compute_transform( + starting_indexes.decadeindex, + self.timeindexes_to_close + .decadeindex + .last + .as_mut() + .as_mut() + .unwrap() + .mut_vec(), + |(i, close, ..)| { + ( + i, + OHLCDollars { + open: *self + .timeindexes_to_open + .decadeindex + .first + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + high: *self + .timeindexes_to_high + .decadeindex + .max + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + low: *self + .timeindexes_to_low + .decadeindex + .min + .as_mut() + .unwrap() + .get(i) + .unwrap() + .unwrap(), + close, + }, + ) + }, + exit, + )?; + Ok(()) } pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> { vec![ - self.dateindex_to_close.any_vec(), - self.dateindex_to_close_in_cents.any_vec(), - self.dateindex_to_high.any_vec(), - self.dateindex_to_high_in_cents.any_vec(), - self.dateindex_to_low.any_vec(), - self.dateindex_to_low_in_cents.any_vec(), - self.dateindex_to_ohlc.any_vec(), - self.dateindex_to_ohlc_in_cents.any_vec(), - self.dateindex_to_open.any_vec(), - self.dateindex_to_open_in_cents.any_vec(), - self.dateindex_to_sats_per_dollar.any_vec(), - self.height_to_close.any_vec(), - self.height_to_close_in_cents.any_vec(), - self.height_to_high.any_vec(), - self.height_to_high_in_cents.any_vec(), - self.height_to_low.any_vec(), - self.height_to_low_in_cents.any_vec(), - self.height_to_ohlc.any_vec(), - self.height_to_ohlc_in_cents.any_vec(), - self.height_to_open.any_vec(), - self.height_to_open_in_cents.any_vec(), - self.height_to_sats_per_dollar.any_vec(), + vec![ + self.dateindex_to_close.any_vec(), + self.dateindex_to_close_in_cents.any_vec(), + self.dateindex_to_high.any_vec(), + self.dateindex_to_high_in_cents.any_vec(), + self.dateindex_to_low.any_vec(), + self.dateindex_to_low_in_cents.any_vec(), + self.dateindex_to_ohlc.any_vec(), + self.dateindex_to_ohlc_in_cents.any_vec(), + self.dateindex_to_open.any_vec(), + self.dateindex_to_open_in_cents.any_vec(), + self.dateindex_to_sats_per_dollar.any_vec(), + self.height_to_close.any_vec(), + self.height_to_close_in_cents.any_vec(), + self.height_to_high.any_vec(), + self.height_to_high_in_cents.any_vec(), + self.height_to_low.any_vec(), + self.height_to_low_in_cents.any_vec(), + self.height_to_ohlc.any_vec(), + self.height_to_ohlc_in_cents.any_vec(), + self.height_to_open.any_vec(), + self.height_to_open_in_cents.any_vec(), + self.height_to_sats_per_dollar.any_vec(), + self.weekindex_to_ohlc.any_vec(), + self.difficultyepoch_to_ohlc.any_vec(), + self.monthindex_to_ohlc.any_vec(), + self.yearindex_to_ohlc.any_vec(), + // self.halvingepoch_to_ohlc.any_vec(), + self.decadeindex_to_ohlc.any_vec(), + ], + self.timeindexes_to_close.as_any_vecs(), + self.timeindexes_to_high.as_any_vecs(), + self.timeindexes_to_low.as_any_vecs(), + self.timeindexes_to_open.as_any_vecs(), + self.chainindexes_to_close.as_any_vecs(), + self.chainindexes_to_high.as_any_vecs(), + self.chainindexes_to_low.as_any_vecs(), + self.chainindexes_to_open.as_any_vecs(), ] + .concat() } } diff --git a/crates/brk_computer/src/storage/vecs/stats/from_date.rs b/crates/brk_computer/src/storage/vecs/stats/from_date.rs new file mode 100644 index 000000000..bde328afb --- /dev/null +++ b/crates/brk_computer/src/storage/vecs/stats/from_date.rs @@ -0,0 +1,93 @@ +use std::path::Path; + +use brk_core::{Dateindex, Decadeindex, Monthindex, Weekindex, Yearindex}; +use brk_exit::Exit; +use brk_vec::{AnyStorableVec, Compressed}; + +use crate::storage::vecs::{Indexes, base::StorableVec, indexes}; + +use super::{ComputedType, StorableVecBuilder, StorableVecGeneatorOptions}; + +#[derive(Clone)] +pub struct StorableVecsStatsFromDate +where + T: ComputedType + PartialOrd, +{ + pub weekindex: StorableVecBuilder, + pub monthindex: StorableVecBuilder, + pub yearindex: StorableVecBuilder, + pub decadeindex: StorableVecBuilder, +} + +impl StorableVecsStatsFromDate +where + T: ComputedType + Ord + From, + f64: From, +{ + pub fn forced_import( + path: &Path, + compressed: Compressed, + options: StorableVecGeneatorOptions, + ) -> color_eyre::Result { + let options = options.remove_percentiles(); + + Ok(Self { + weekindex: StorableVecBuilder::forced_import(path, compressed, options)?, + monthindex: StorableVecBuilder::forced_import(path, compressed, options)?, + yearindex: StorableVecBuilder::forced_import(path, compressed, options)?, + decadeindex: StorableVecBuilder::forced_import(path, compressed, options)?, + }) + } + + pub fn compute( + &mut self, + source: &mut StorableVec, + indexes: &mut indexes::Vecs, + starting_indexes: &Indexes, + exit: &Exit, + ) -> color_eyre::Result<()> { + self.weekindex.compute( + starting_indexes.weekindex, + source, + indexes.weekindex_to_first_dateindex.mut_vec(), + indexes.weekindex_to_last_dateindex.mut_vec(), + exit, + )?; + + self.monthindex.compute( + starting_indexes.monthindex, + source, + indexes.monthindex_to_first_dateindex.mut_vec(), + indexes.monthindex_to_last_dateindex.mut_vec(), + exit, + )?; + + self.yearindex.from_aligned( + starting_indexes.yearindex, + &mut self.monthindex, + indexes.yearindex_to_first_monthindex.mut_vec(), + indexes.yearindex_to_last_monthindex.mut_vec(), + exit, + )?; + + self.decadeindex.from_aligned( + starting_indexes.decadeindex, + &mut self.yearindex, + indexes.decadeindex_to_first_yearindex.mut_vec(), + indexes.decadeindex_to_last_yearindex.mut_vec(), + exit, + )?; + + Ok(()) + } + + pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> { + [ + self.weekindex.as_any_vecs(), + self.monthindex.as_any_vecs(), + self.yearindex.as_any_vecs(), + self.decadeindex.as_any_vecs(), + ] + .concat() + } +} diff --git a/crates/brk_computer/src/storage/vecs/stats/grouped.rs b/crates/brk_computer/src/storage/vecs/stats/from_height.rs similarity index 97% rename from crates/brk_computer/src/storage/vecs/stats/grouped.rs rename to crates/brk_computer/src/storage/vecs/stats/from_height.rs index c5d7cfb52..f1643c61b 100644 --- a/crates/brk_computer/src/storage/vecs/stats/grouped.rs +++ b/crates/brk_computer/src/storage/vecs/stats/from_height.rs @@ -9,9 +9,9 @@ use crate::storage::vecs::{Indexes, base::StorableVec, indexes}; use super::{ComputedType, StorableVecBuilder, StorableVecGeneatorOptions}; #[derive(Clone)] -pub struct StorableVecGeneatorByIndex +pub struct StorableVecsStatsFromHeight where - T: ComputedType + Ord, + T: ComputedType + PartialOrd, { pub dateindex: StorableVecBuilder, pub weekindex: StorableVecBuilder, @@ -22,7 +22,7 @@ where pub decadeindex: StorableVecBuilder, } -impl StorableVecGeneatorByIndex +impl StorableVecsStatsFromHeight where T: ComputedType + Ord + From, f64: From, diff --git a/crates/brk_computer/src/storage/vecs/stats/from_height_strict.rs b/crates/brk_computer/src/storage/vecs/stats/from_height_strict.rs new file mode 100644 index 000000000..12a1af80d --- /dev/null +++ b/crates/brk_computer/src/storage/vecs/stats/from_height_strict.rs @@ -0,0 +1,63 @@ +use std::path::Path; + +use brk_core::{Difficultyepoch, Height}; +use brk_exit::Exit; +use brk_vec::{AnyStorableVec, Compressed}; + +use crate::storage::vecs::{Indexes, base::StorableVec, indexes}; + +use super::{ComputedType, StorableVecBuilder, StorableVecGeneatorOptions}; + +#[derive(Clone)] +pub struct StorableVecsStatsFromHeightStrict +where + T: ComputedType + PartialOrd, +{ + pub difficultyepoch: StorableVecBuilder, + // pub halvingepoch: StorableVecGeneator, // TODO +} + +impl StorableVecsStatsFromHeightStrict +where + T: ComputedType + Ord + From, + f64: From, +{ + pub fn forced_import( + path: &Path, + compressed: Compressed, + options: StorableVecGeneatorOptions, + ) -> color_eyre::Result { + let options = options.remove_percentiles(); + + Ok(Self { + difficultyepoch: StorableVecBuilder::forced_import(path, compressed, options)?, + // halvingepoch: StorableVecGeneator::forced_import(path, compressed, options)?, + }) + } + + pub fn compute( + &mut self, + source: &mut StorableVec, + indexes: &mut indexes::Vecs, + starting_indexes: &Indexes, + exit: &Exit, + ) -> color_eyre::Result<()> { + self.difficultyepoch.compute( + starting_indexes.difficultyepoch, + source, + indexes.difficultyepoch_to_first_height.mut_vec(), + indexes.difficultyepoch_to_last_height.mut_vec(), + exit, + )?; + + Ok(()) + } + + pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> { + [ + self.difficultyepoch.as_any_vecs(), + // self.halvingepoch.as_any_vecs(), + ] + .concat() + } +} diff --git a/crates/brk_computer/src/storage/vecs/stats/generic.rs b/crates/brk_computer/src/storage/vecs/stats/generic.rs index beb0ef7be..0b4856d08 100644 --- a/crates/brk_computer/src/storage/vecs/stats/generic.rs +++ b/crates/brk_computer/src/storage/vecs/stats/generic.rs @@ -13,17 +13,17 @@ where I: StoredIndex, T: ComputedType, { - first: Option>, - average: Option>, - sum: Option>, - max: Option>, - _90p: Option>, - _75p: Option>, - median: Option>, - _25p: Option>, - _10p: Option>, - min: Option>, - last: Option>, + pub first: Option>, + pub average: Option>, + pub sum: Option>, + pub max: Option>, + pub _90p: Option>, + pub _75p: Option>, + pub median: Option>, + pub _25p: Option>, + pub _10p: Option>, + pub min: Option>, + pub last: Option>, } impl StorableVecBuilder @@ -226,7 +226,7 @@ where .first .as_mut() .unwrap() - .get(last_index) + .get(first_index) .unwrap() .cloned() .unwrap(); @@ -287,6 +287,8 @@ where .into_iter() .map(|v| f64::from(v)) .fold(0.0, |a, b| a + b); + // TODO: Multiply by count then divide by total + // Right now it's not 100% accurate as there could be more or less elements in the lower timeframe (28 days vs 31 days in a month for example) let avg = T::from(total / len); average.forced_push_at(i, avg, exit)?; } diff --git a/crates/brk_computer/src/storage/vecs/stats/mod.rs b/crates/brk_computer/src/storage/vecs/stats/mod.rs index e3b3d25f7..359184006 100644 --- a/crates/brk_computer/src/storage/vecs/stats/mod.rs +++ b/crates/brk_computer/src/storage/vecs/stats/mod.rs @@ -1,7 +1,11 @@ +mod from_date; +mod from_height; +mod from_height_strict; mod generic; -mod grouped; mod stored_type; +pub use from_date::*; +pub use from_height::*; +pub use from_height_strict::*; pub use generic::*; -pub use grouped::*; pub use stored_type::*; diff --git a/crates/brk_core/src/structs/dollars.rs b/crates/brk_core/src/structs/dollars.rs index 5544457b2..993bf789a 100644 --- a/crates/brk_core/src/structs/dollars.rs +++ b/crates/brk_core/src/structs/dollars.rs @@ -1,3 +1,5 @@ +use std::ops::{Add, Div}; + use derive_deref::Deref; use serde::Serialize; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; @@ -5,7 +7,18 @@ use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; use super::Cents; #[derive( - Debug, Default, Clone, Copy, Deref, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize, + Debug, + Default, + Clone, + Copy, + PartialEq, + PartialOrd, + Deref, + FromBytes, + Immutable, + IntoBytes, + KnownLayout, + Serialize, )] pub struct Dollars(f64); @@ -26,3 +39,32 @@ impl From for f64 { value.0 } } + +impl From for Dollars { + fn from(value: usize) -> Self { + Self(value as f64) + } +} + +impl Add for Dollars { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +impl Div for Dollars { + type Output = Self; + fn div(self, rhs: usize) -> Self::Output { + Self(self.0 / rhs as f64) + } +} + +impl Eq for Dollars {} + +#[allow(clippy::derive_ord_xor_partial_ord)] +impl Ord for Dollars { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.partial_cmp(&other.0).unwrap() + } +} diff --git a/crates/brk_core/src/structs/ohlc.rs b/crates/brk_core/src/structs/ohlc.rs index 0b55c89c1..5bf830780 100644 --- a/crates/brk_core/src/structs/ohlc.rs +++ b/crates/brk_core/src/structs/ohlc.rs @@ -1,8 +1,10 @@ +use std::ops::{Add, Div}; + use derive_deref::Deref; use serde::Serialize; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; -use super::{Cents, Dollars}; +use super::{Cents, Dollars, Sats}; #[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize)] #[repr(C)] @@ -122,6 +124,44 @@ impl From> for Open { } } +impl From for Open { + fn from(value: usize) -> Self { + Self(Dollars::from(value)) + } +} + +impl From for Open { + fn from(value: f64) -> Self { + Self(Dollars::from(value)) + } +} + +impl From> for f64 { + fn from(value: Open) -> Self { + Self::from(value.0) + } +} + +impl Add for Open +where + T: Add, +{ + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +impl Div for Open +where + T: Div, +{ + type Output = Self; + fn div(self, rhs: usize) -> Self::Output { + Self(self.0 / rhs) + } +} + #[derive( Debug, Default, @@ -161,6 +201,44 @@ impl From> for High { } } +impl From for High { + fn from(value: usize) -> Self { + Self(Dollars::from(value)) + } +} + +impl From for High { + fn from(value: f64) -> Self { + Self(Dollars::from(value)) + } +} + +impl From> for f64 { + fn from(value: High) -> Self { + Self::from(value.0) + } +} + +impl Add for High +where + T: Add, +{ + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +impl Div for High +where + T: Div, +{ + type Output = Self; + fn div(self, rhs: usize) -> Self::Output { + Self(self.0 / rhs) + } +} + #[derive( Debug, Default, @@ -200,6 +278,44 @@ impl From> for Low { } } +impl From for Low { + fn from(value: usize) -> Self { + Self(Dollars::from(value)) + } +} + +impl From for Low { + fn from(value: f64) -> Self { + Self(Dollars::from(value)) + } +} + +impl From> for f64 { + fn from(value: Low) -> Self { + Self::from(value.0) + } +} + +impl Add for Low +where + T: Add, +{ + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +impl Div for Low +where + T: Div, +{ + type Output = Self; + fn div(self, rhs: usize) -> Self::Output { + Self(self.0 / rhs) + } +} + #[derive( Debug, Default, @@ -229,3 +345,59 @@ impl From> for Close { Self(Dollars::from(*value)) } } + +impl From for Close { + fn from(value: usize) -> Self { + Self(Dollars::from(value)) + } +} + +impl From for Close { + fn from(value: usize) -> Self { + Self(Sats::from(value)) + } +} + +impl From for Close { + fn from(value: f64) -> Self { + Self(Dollars::from(value)) + } +} + +impl From for Close { + fn from(value: f64) -> Self { + Self(Sats::from(value)) + } +} + +impl From> for f64 { + fn from(value: Close) -> Self { + Self::from(value.0) + } +} + +impl From> for f64 { + fn from(value: Close) -> Self { + Self::from(value.0) + } +} + +impl Add for Close +where + T: Add, +{ + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +impl Div for Close +where + T: Div, +{ + type Output = Self; + fn div(self, rhs: usize) -> Self::Output { + Self(self.0 / rhs) + } +} diff --git a/crates/brk_core/src/structs/sats.rs b/crates/brk_core/src/structs/sats.rs index d57571b36..e3f608560 100644 --- a/crates/brk_core/src/structs/sats.rs +++ b/crates/brk_core/src/structs/sats.rs @@ -97,12 +97,37 @@ impl Div for Sats { } } +impl Div for Sats { + type Output = Self; + fn div(self, rhs: usize) -> Self::Output { + Self(self.0 / rhs as u64) + } +} + impl From for Sats { fn from(value: u64) -> Self { Self(value) } } +impl From for Sats { + fn from(value: usize) -> Self { + Self(value as u64) + } +} + +impl From for Sats { + fn from(value: f64) -> Self { + Self(value as u64) + } +} + +impl From for f64 { + fn from(value: Sats) -> Self { + value.0 as f64 + } +} + impl From for Sats { fn from(value: Amount) -> Self { Self(value.to_sat()) diff --git a/crates/brk_vec/src/lib.rs b/crates/brk_vec/src/lib.rs index 6311810cd..0d473e9a2 100644 --- a/crates/brk_vec/src/lib.rs +++ b/crates/brk_vec/src/lib.rs @@ -193,13 +193,19 @@ where return Err(Error::UnsupportedUnflushedState); } - let len = self.stored_len(); + let len = self + .base() + .read_stored_length() + .unwrap() + .to_usize() + .unwrap(); let from = from.map_or(0, |from| { if from >= 0 { from as usize } else { - (len as i64 + from) as usize + let from = len as i64 + from; + if from < 0 { 0 } else { from as usize } } }); @@ -207,7 +213,9 @@ where if to >= 0 { to as usize } else { - ((len - 1) as i64 + to) as usize + let max = len - 1; + let to = max as i64 + to; + if to > max as i64 { max } else { to as usize } } }); @@ -228,11 +236,7 @@ where }; let values = Self::decode_page_( - self.base() - .read_stored_length() - .unwrap() - .to_usize() - .unwrap(), + len, page_index, &self.base().open_file().unwrap(), pages_meta.as_ref(),