diff --git a/crates/brk_computer/src/grouped/lazy2_from_dateindex.rs b/crates/brk_computer/src/grouped/lazy2_from_dateindex.rs index 9c47e8e16..27ac9d5f3 100644 --- a/crates/brk_computer/src/grouped/lazy2_from_dateindex.rs +++ b/crates/brk_computer/src/grouped/lazy2_from_dateindex.rs @@ -104,7 +104,10 @@ where Some(("weekindex".to_string(), self.weekindex.to_tree_node())), Some(("monthindex".to_string(), self.monthindex.to_tree_node())), Some(("quarterindex".to_string(), self.quarterindex.to_tree_node())), - Some(("semesterindex".to_string(), self.semesterindex.to_tree_node())), + Some(( + "semesterindex".to_string(), + self.semesterindex.to_tree_node(), + )), Some(("yearindex".to_string(), self.yearindex.to_tree_node())), Some(("decadeindex".to_string(), self.decadeindex.to_tree_node())), ] diff --git a/crates/brk_computer/src/grouped/lazy2_from_height.rs b/crates/brk_computer/src/grouped/lazy2_from_height.rs new file mode 100644 index 000000000..8a86530ba --- /dev/null +++ b/crates/brk_computer/src/grouped/lazy2_from_height.rs @@ -0,0 +1,163 @@ +use brk_traversable::Traversable; +use brk_types::{ + DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, SemesterIndex, + Version, WeekIndex, YearIndex, +}; +use schemars::JsonSchema; +use vecdb::{AnyExportableVec, BinaryTransform, IterableBoxedVec, LazyVecFrom2}; + +use super::{ComputedVecValue, ComputedVecsFromHeight, LazyTransform2Builder}; + +const VERSION: Version = Version::ZERO; + +/// Lazy binary transform from two `ComputedVecsFromHeight` sources. +#[derive(Clone)] +pub struct LazyVecsFrom2FromHeight +where + T: ComputedVecValue + PartialOrd + JsonSchema, + S1T: ComputedVecValue, + S2T: ComputedVecValue, +{ + pub height: LazyVecFrom2, + pub height_extra: LazyTransform2Builder, + pub dateindex: LazyTransform2Builder, + pub weekindex: LazyTransform2Builder, + pub difficultyepoch: LazyTransform2Builder, + pub monthindex: LazyTransform2Builder, + pub quarterindex: LazyTransform2Builder, + pub semesterindex: LazyTransform2Builder, + pub yearindex: LazyTransform2Builder, + pub decadeindex: LazyTransform2Builder, +} + +impl LazyVecsFrom2FromHeight +where + T: ComputedVecValue + JsonSchema + 'static, + S1T: ComputedVecValue + JsonSchema, + S2T: ComputedVecValue + JsonSchema, +{ + /// Create from two `ComputedVecsFromHeight` sources with explicit height sources. + pub fn from_computed>( + name: &str, + version: Version, + height_source1: IterableBoxedVec, + height_source2: IterableBoxedVec, + source1: &ComputedVecsFromHeight, + source2: &ComputedVecsFromHeight, + ) -> Self { + let v = version + VERSION; + + Self { + height: LazyVecFrom2::transformed::(name, v, height_source1, height_source2), + height_extra: LazyTransform2Builder::from_eager::( + name, + v, + &source1.height_extra, + &source2.height_extra, + ), + dateindex: LazyTransform2Builder::from_eager::( + name, + v, + &source1.dateindex, + &source2.dateindex, + ), + weekindex: LazyTransform2Builder::from_lazy::( + name, + v, + &source1.weekindex, + &source2.weekindex, + ), + difficultyepoch: LazyTransform2Builder::from_eager::( + name, + v, + &source1.difficultyepoch, + &source2.difficultyepoch, + ), + monthindex: LazyTransform2Builder::from_lazy::( + name, + v, + &source1.monthindex, + &source2.monthindex, + ), + quarterindex: LazyTransform2Builder::from_lazy::( + name, + v, + &source1.quarterindex, + &source2.quarterindex, + ), + semesterindex: LazyTransform2Builder::from_lazy::( + name, + v, + &source1.semesterindex, + &source2.semesterindex, + ), + yearindex: LazyTransform2Builder::from_lazy::( + name, + v, + &source1.yearindex, + &source2.yearindex, + ), + decadeindex: LazyTransform2Builder::from_lazy::( + name, + v, + &source1.decadeindex, + &source2.decadeindex, + ), + } + } +} + +impl Traversable for LazyVecsFrom2FromHeight +where + T: ComputedVecValue + JsonSchema, + S1T: ComputedVecValue, + S2T: ComputedVecValue, +{ + fn to_tree_node(&self) -> brk_traversable::TreeNode { + let height_extra_node = self.height_extra.to_tree_node(); + brk_traversable::TreeNode::Branch( + [ + Some(("height".to_string(), self.height.to_tree_node())), + if height_extra_node.is_empty() { + None + } else { + Some(("height_extra".to_string(), height_extra_node)) + }, + Some(("dateindex".to_string(), self.dateindex.to_tree_node())), + Some(("weekindex".to_string(), self.weekindex.to_tree_node())), + Some(( + "difficultyepoch".to_string(), + self.difficultyepoch.to_tree_node(), + )), + Some(("monthindex".to_string(), self.monthindex.to_tree_node())), + Some(("quarterindex".to_string(), self.quarterindex.to_tree_node())), + Some(( + "semesterindex".to_string(), + self.semesterindex.to_tree_node(), + )), + Some(("yearindex".to_string(), self.yearindex.to_tree_node())), + Some(("decadeindex".to_string(), self.decadeindex.to_tree_node())), + ] + .into_iter() + .flatten() + .collect(), + ) + .merge_branches() + .unwrap() + } + + fn iter_any_exportable(&self) -> impl Iterator { + let mut iter: Box> = + Box::new(self.height.iter_any_exportable()); + iter = Box::new(iter.chain(self.height_extra.iter_any_exportable())); + iter = Box::new(iter.chain(self.dateindex.iter_any_exportable())); + iter = Box::new(iter.chain(self.weekindex.iter_any_exportable())); + iter = Box::new(iter.chain(self.difficultyepoch.iter_any_exportable())); + iter = Box::new(iter.chain(self.monthindex.iter_any_exportable())); + iter = Box::new(iter.chain(self.quarterindex.iter_any_exportable())); + iter = Box::new(iter.chain(self.semesterindex.iter_any_exportable())); + iter = Box::new(iter.chain(self.yearindex.iter_any_exportable())); + iter = Box::new(iter.chain(self.decadeindex.iter_any_exportable())); + iter + } +} diff --git a/crates/brk_computer/src/grouped/mod.rs b/crates/brk_computer/src/grouped/mod.rs index 6d4123416..a4031f5de 100644 --- a/crates/brk_computer/src/grouped/mod.rs +++ b/crates/brk_computer/src/grouped/mod.rs @@ -9,6 +9,7 @@ mod computed_from_height; mod computed_from_height_strict; mod computed_from_txindex; mod lazy2_from_dateindex; +mod lazy2_from_height; mod lazy_from_dateindex; mod lazy_from_height; mod lazy_value_from_dateindex; @@ -40,6 +41,7 @@ pub use lazy_from_height::*; pub use lazy_value_from_dateindex::*; pub use lazy_value_height::*; pub use lazy2_from_dateindex::*; +pub use lazy2_from_height::*; // pub use lazy_from_height_strict::*; // pub use lazy_from_txindex::*; pub use price_percentiles::*; diff --git a/crates/brk_computer/src/grouped/transforms.rs b/crates/brk_computer/src/grouped/transforms.rs index 4ed53e815..a56425cb5 100644 --- a/crates/brk_computer/src/grouped/transforms.rs +++ b/crates/brk_computer/src/grouped/transforms.rs @@ -1,4 +1,4 @@ -use brk_types::{Bitcoin, Close, Dollars, Sats, StoredF32}; +use brk_types::{Bitcoin, Close, Dollars, Sats, StoredF32, StoredF64}; use vecdb::{BinaryTransform, UnaryTransform}; /// (Dollars, Dollars) -> Dollars addition @@ -162,4 +162,53 @@ impl UnaryTransform for DollarsTimesTenths { fn apply(d: Dollars) -> Dollars { d * (V as f64 / 10.0) } -} \ No newline at end of file +} + +// === Percentage Transforms (a/b × 100) === + +/// (Bitcoin, Bitcoin) -> StoredF64 percentage (a/b × 100) +/// Used for supply ratio calculations like supply_in_profit / total_supply × 100 +pub struct PercentageBtcF64; + +impl BinaryTransform for PercentageBtcF64 { + #[inline(always)] + fn apply(numerator: Bitcoin, denominator: Bitcoin) -> StoredF64 { + // Bitcoin / Bitcoin returns StoredF64, so dereference and multiply + StoredF64::from(*(numerator / denominator) * 100.0) + } +} + +/// (Dollars, Dollars) -> StoredF32 percentage (a/b × 100) +/// Used for unrealized/realized ratio calculations +pub struct PercentageDollarsF32; + +impl BinaryTransform for PercentageDollarsF32 { + #[inline(always)] + fn apply(numerator: Dollars, denominator: Dollars) -> StoredF32 { + // Dollars / Dollars returns StoredF64, so dereference and multiply + StoredF32::from(*(numerator / denominator) * 100.0) + } +} + +/// (Dollars, Dollars) -> StoredF32 negated percentage (-(a/b × 100)) +/// Used for negated loss ratio calculations, avoiding lazy-from-lazy chains. +pub struct NegPercentageDollarsF32; + +impl BinaryTransform for NegPercentageDollarsF32 { + #[inline(always)] + fn apply(numerator: Dollars, denominator: Dollars) -> StoredF32 { + // Dollars / Dollars returns StoredF64, so dereference and multiply + StoredF32::from(-(*(numerator / denominator) * 100.0)) + } +} + +/// (Sats, Sats) -> StoredF64 percentage (a/b × 100) +/// Used for supply ratio calculations (equivalent to Bitcoin/Bitcoin since 1e8 cancels) +pub struct PercentageSatsF64; + +impl BinaryTransform for PercentageSatsF64 { + #[inline(always)] + fn apply(numerator: Sats, denominator: Sats) -> StoredF64 { + StoredF64::from((*numerator as f64 / *denominator as f64) * 100.0) + } +} diff --git a/crates/brk_computer/src/stateful/compute/block_loop.rs b/crates/brk_computer/src/stateful/compute/block_loop.rs index 162cf243d..363fee429 100644 --- a/crates/brk_computer/src/stateful/compute/block_loop.rs +++ b/crates/brk_computer/src/stateful/compute/block_loop.rs @@ -9,7 +9,7 @@ use rayon::prelude::*; use vecdb::{Exit, GenericStoredVec, IterableVec, TypedVecIterator, VecIndex}; use crate::{ - chain, indexes, price, txins, + chain, indexes, price, stateful::{ address::AddressTypeToAddressCount, compute::write::{process_address_updates, write}, @@ -19,14 +19,15 @@ use crate::{ }, states::{BlockState, Transacted}, }, + txins, utils::OptionExt, }; use super::{ super::{ + RangeMap, cohorts::{AddressCohorts, DynCohortVecs, UTXOCohorts}, vecs::Vecs, - RangeMap, }, BIP30_DUPLICATE_HEIGHT_1, BIP30_DUPLICATE_HEIGHT_2, BIP30_ORIGINAL_HEIGHT_1, BIP30_ORIGINAL_HEIGHT_2, ComputeContext, FLUSH_INTERVAL, TxInIterators, TxOutIterators, @@ -62,8 +63,6 @@ pub fn process_blocks( ctx.price.is_some() ); - info!("Setting up references..."); - // References to vectors using correct field paths // From indexer.vecs: let height_to_first_txindex = &indexer.vecs.tx.height_to_first_txindex; @@ -97,8 +96,6 @@ pub fn process_blocks( let height_to_price_vec = &ctx.height_to_price; let height_to_timestamp_vec = &ctx.height_to_timestamp; - info!("Creating iterators..."); - // Create iterators for sequential access let mut height_to_first_txindex_iter = height_to_first_txindex.into_iter(); let mut height_to_first_txoutindex_iter = height_to_first_txoutindex.into_iter(); @@ -116,12 +113,9 @@ pub fn process_blocks( let mut height_to_price_iter = height_to_price.map(|v| v.into_iter()); let mut dateindex_to_price_iter = dateindex_to_price.map(|v| v.into_iter()); - info!("Creating readers..."); - let mut vr = VecsReaders::new(&vecs.any_address_indexes, &vecs.addresses_data); // Build txindex -> height lookup map for efficient prev_height computation - info!("Building txindex_to_height map..."); let mut txindex_to_height: RangeMap = { let mut map = RangeMap::with_capacity(last_height.to_usize() + 1); for first_txindex in indexer.vecs.tx.height_to_first_txindex.into_iter() { @@ -134,8 +128,6 @@ pub fn process_blocks( let mut txout_iters = TxOutIterators::new(indexer); let mut txin_iters = TxInIterators::new(indexer, txins, &mut txindex_to_height); - info!("Creating address iterators..."); - // Create iterators for first address indexes per type let mut first_p2a_iter = indexer .vecs @@ -178,8 +170,6 @@ pub fn process_blocks( .height_to_first_p2wshaddressindex .into_iter(); - info!("Recovering running totals..."); - // Track running totals - recover from previous height if resuming let ( mut unspendable_supply, @@ -187,28 +177,23 @@ pub fn process_blocks( mut addresstype_to_addr_count, mut addresstype_to_empty_addr_count, ) = if starting_height > Height::ZERO { - info!("Reading unspendable_supply..."); let prev_height = starting_height.decremented().unwrap(); let unspendable = vecs .height_to_unspendable_supply .into_iter() .get_unwrap(prev_height); - info!("Reading opreturn_supply..."); let opreturn = vecs .height_to_opreturn_supply .into_iter() .get_unwrap(prev_height); - info!("Reading addresstype_to_addr_count..."); let addr_count = AddressTypeToAddressCount::from(( &vecs.addresstype_to_height_to_addr_count, starting_height, )); - info!("Reading addresstype_to_empty_addr_count..."); let empty_addr_count = AddressTypeToAddressCount::from(( &vecs.addresstype_to_height_to_empty_addr_count, starting_height, )); - info!("Recovery complete."); (unspendable, opreturn, addr_count, empty_addr_count) } else { ( @@ -221,8 +206,6 @@ pub fn process_blocks( let mut cache = AddressCache::new(); - info!("Starting main block iteration..."); - // Main block iteration for height in starting_height.to_usize()..=last_height.to_usize() { let height = Height::from(height); diff --git a/crates/brk_computer/src/stateful/metrics/mod.rs b/crates/brk_computer/src/stateful/metrics/mod.rs index a483e2955..25104322e 100644 --- a/crates/brk_computer/src/stateful/metrics/mod.rs +++ b/crates/brk_computer/src/stateful/metrics/mod.rs @@ -53,13 +53,20 @@ impl CohortMetrics { pub fn forced_import(cfg: &ImportConfig) -> Result { let compute_dollars = cfg.compute_dollars(); + let supply = SupplyMetrics::forced_import(cfg)?; + let unrealized = compute_dollars .then(|| UnrealizedMetrics::forced_import(cfg)) .transpose()?; + let relative = unrealized + .as_ref() + .map(|u| RelativeMetrics::forced_import(cfg, u, &supply)) + .transpose()?; + Ok(Self { filter: cfg.filter.clone(), - supply: SupplyMetrics::forced_import(cfg)?, + supply, activity: ActivityMetrics::forced_import(cfg)?, realized: compute_dollars .then(|| RealizedMetrics::forced_import(cfg)) @@ -67,10 +74,7 @@ impl CohortMetrics { price_paid: compute_dollars .then(|| PricePaidMetrics::forced_import(cfg)) .transpose()?, - relative: unrealized - .as_ref() - .map(|u| RelativeMetrics::forced_import(cfg, u)) - .transpose()?, + relative, unrealized, }) } diff --git a/crates/brk_computer/src/stateful/metrics/realized.rs b/crates/brk_computer/src/stateful/metrics/realized.rs index 24a5d65e6..ad904463d 100644 --- a/crates/brk_computer/src/stateful/metrics/realized.rs +++ b/crates/brk_computer/src/stateful/metrics/realized.rs @@ -11,7 +11,8 @@ use crate::{ Indexes, grouped::{ ComputedRatioVecsFromDateIndex, ComputedVecsFromDateIndex, ComputedVecsFromHeight, - LazyVecsFromHeight, Source, VecBuilderOptions, + LazyVecsFrom2FromHeight, LazyVecsFromHeight, PercentageDollarsF32, Source, + VecBuilderOptions, }, indexes, price, stateful::states::RealizedState, @@ -40,10 +41,13 @@ pub struct RealizedMetrics { pub indexes_to_net_realized_pnl: ComputedVecsFromHeight, pub indexes_to_realized_value: ComputedVecsFromHeight, - // === Realized vs Realized Cap Ratios === - pub indexes_to_realized_profit_rel_to_realized_cap: ComputedVecsFromHeight, - pub indexes_to_realized_loss_rel_to_realized_cap: ComputedVecsFromHeight, - pub indexes_to_net_realized_pnl_rel_to_realized_cap: ComputedVecsFromHeight, + // === Realized vs Realized Cap Ratios (lazy) === + pub indexes_to_realized_profit_rel_to_realized_cap: + LazyVecsFrom2FromHeight, + pub indexes_to_realized_loss_rel_to_realized_cap: + LazyVecsFrom2FromHeight, + pub indexes_to_net_realized_pnl_rel_to_realized_cap: + LazyVecsFrom2FromHeight, // === Total Realized PnL === pub indexes_to_total_realized_pnl: LazyVecsFromHeight, @@ -135,21 +139,75 @@ impl RealizedMetrics { &indexes_to_realized_value, ); + // Extract vecs needed for lazy ratio construction + let height_to_realized_cap: EagerVec> = + EagerVec::forced_import(cfg.db, &cfg.name("realized_cap"), cfg.version + v0)?; + + let indexes_to_realized_cap = ComputedVecsFromHeight::forced_import( + cfg.db, + &cfg.name("realized_cap"), + Source::None, + cfg.version + v0, + cfg.indexes, + last, + )?; + + let height_to_realized_profit: EagerVec> = + EagerVec::forced_import(cfg.db, &cfg.name("realized_profit"), cfg.version + v0)?; + + let indexes_to_realized_profit = ComputedVecsFromHeight::forced_import( + cfg.db, + &cfg.name("realized_profit"), + Source::None, + cfg.version + v0, + cfg.indexes, + sum_cum, + )?; + + let indexes_to_net_realized_pnl = ComputedVecsFromHeight::forced_import( + cfg.db, + &cfg.name("net_realized_pnl"), + Source::Compute, + cfg.version + v0, + cfg.indexes, + sum_cum, + )?; + + // Construct lazy ratio vecs (before struct assignment to satisfy borrow checker) + let indexes_to_realized_profit_rel_to_realized_cap = + LazyVecsFrom2FromHeight::from_computed::( + &cfg.name("realized_profit_rel_to_realized_cap"), + cfg.version + v1, + height_to_realized_profit.boxed_clone(), + height_to_realized_cap.boxed_clone(), + &indexes_to_realized_profit, + &indexes_to_realized_cap, + ); + + let indexes_to_realized_loss_rel_to_realized_cap = + LazyVecsFrom2FromHeight::from_computed::( + &cfg.name("realized_loss_rel_to_realized_cap"), + cfg.version + v1, + height_to_realized_loss.boxed_clone(), + height_to_realized_cap.boxed_clone(), + &indexes_to_realized_loss, + &indexes_to_realized_cap, + ); + + let indexes_to_net_realized_pnl_rel_to_realized_cap = + LazyVecsFrom2FromHeight::from_computed::( + &cfg.name("net_realized_pnl_rel_to_realized_cap"), + cfg.version + v1, + indexes_to_net_realized_pnl.height.as_ref().unwrap().boxed_clone(), + height_to_realized_cap.boxed_clone(), + &indexes_to_net_realized_pnl, + &indexes_to_realized_cap, + ); + Ok(Self { // === Realized Cap === - height_to_realized_cap: EagerVec::forced_import( - cfg.db, - &cfg.name("realized_cap"), - cfg.version + v0, - )?, - indexes_to_realized_cap: ComputedVecsFromHeight::forced_import( - cfg.db, - &cfg.name("realized_cap"), - Source::None, - cfg.version + v0, - cfg.indexes, - last, - )?, + height_to_realized_cap, + indexes_to_realized_cap, indexes_to_realized_price: ComputedVecsFromHeight::forced_import( cfg.db, &cfg.name("realized_price"), @@ -188,57 +246,18 @@ impl RealizedMetrics { )?, // === Realized Profit/Loss === - height_to_realized_profit: EagerVec::forced_import( - cfg.db, - &cfg.name("realized_profit"), - cfg.version + v0, - )?, - indexes_to_realized_profit: ComputedVecsFromHeight::forced_import( - cfg.db, - &cfg.name("realized_profit"), - Source::None, - cfg.version + v0, - cfg.indexes, - sum_cum, - )?, + height_to_realized_profit, + indexes_to_realized_profit, height_to_realized_loss, indexes_to_realized_loss, indexes_to_neg_realized_loss, - indexes_to_net_realized_pnl: ComputedVecsFromHeight::forced_import( - cfg.db, - &cfg.name("net_realized_pnl"), - Source::Compute, - cfg.version + v0, - cfg.indexes, - sum_cum, - )?, + indexes_to_net_realized_pnl, indexes_to_realized_value, - // === Realized vs Realized Cap Ratios === - indexes_to_realized_profit_rel_to_realized_cap: ComputedVecsFromHeight::forced_import( - cfg.db, - &cfg.name("realized_profit_rel_to_realized_cap"), - Source::Compute, - cfg.version + v0, - cfg.indexes, - sum, - )?, - indexes_to_realized_loss_rel_to_realized_cap: ComputedVecsFromHeight::forced_import( - cfg.db, - &cfg.name("realized_loss_rel_to_realized_cap"), - Source::Compute, - cfg.version + v0, - cfg.indexes, - sum, - )?, - indexes_to_net_realized_pnl_rel_to_realized_cap: ComputedVecsFromHeight::forced_import( - cfg.db, - &cfg.name("net_realized_pnl_rel_to_realized_cap"), - Source::Compute, - cfg.version + v1, - cfg.indexes, - sum, - )?, + // === Realized vs Realized Cap Ratios (lazy) === + indexes_to_realized_profit_rel_to_realized_cap, + indexes_to_realized_loss_rel_to_realized_cap, + indexes_to_net_realized_pnl_rel_to_realized_cap, // === Total Realized PnL === indexes_to_total_realized_pnl, @@ -768,40 +787,6 @@ impl RealizedMetrics { exit, )?; - // Ratios relative to realized cap - self.indexes_to_realized_profit_rel_to_realized_cap - .compute_all(indexes, starting_indexes, exit, |vec| { - vec.compute_percentage( - starting_indexes.height, - &self.height_to_realized_profit, - &self.height_to_realized_cap, - exit, - )?; - Ok(()) - })?; - - self.indexes_to_realized_loss_rel_to_realized_cap - .compute_all(indexes, starting_indexes, exit, |vec| { - vec.compute_percentage( - starting_indexes.height, - &self.height_to_realized_loss, - &self.height_to_realized_cap, - exit, - )?; - Ok(()) - })?; - - self.indexes_to_net_realized_pnl_rel_to_realized_cap - .compute_all(indexes, starting_indexes, exit, |vec| { - vec.compute_percentage( - starting_indexes.height, - self.indexes_to_net_realized_pnl.height.u(), - &self.height_to_realized_cap, - exit, - )?; - Ok(()) - })?; - // Net realized PnL cumulative 30d delta self.indexes_to_net_realized_pnl_cumulative_30d_delta .compute_all(starting_indexes, exit, |vec| { diff --git a/crates/brk_computer/src/stateful/metrics/relative.rs b/crates/brk_computer/src/stateful/metrics/relative.rs index 31826ae49..db1d0bfda 100644 --- a/crates/brk_computer/src/stateful/metrics/relative.rs +++ b/crates/brk_computer/src/stateful/metrics/relative.rs @@ -1,6 +1,6 @@ use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Bitcoin, DateIndex, Dollars, Height, StoredF32, StoredF64, Version}; +use brk_types::{Bitcoin, DateIndex, Dollars, Height, Sats, StoredF32, StoredF64, Version}; use vecdb::{ EagerVec, Exit, ImportableVec, IterableCloneableVec, IterableVec, LazyVecFrom1, LazyVecFrom2, Negate, PcoVec, @@ -10,7 +10,8 @@ use crate::{ Indexes, grouped::{ ComputedVecsFromDateIndex, ComputedVecsFromHeight, LazyVecsFrom2FromDateIndex, - LazyVecsFromDateIndex, NegRatio32, Ratio32, Source, VecBuilderOptions, + LazyVecsFromDateIndex, NegPercentageDollarsF32, NegRatio32, PercentageDollarsF32, + PercentageSatsF64, Ratio32, Source, VecBuilderOptions, }, indexes, }; @@ -26,8 +27,10 @@ pub struct RelativeMetrics { // === Supply in Profit/Loss Relative to Own Supply === pub height_to_supply_in_profit_rel_to_own_supply: EagerVec>, pub height_to_supply_in_loss_rel_to_own_supply: EagerVec>, - pub indexes_to_supply_in_profit_rel_to_own_supply: ComputedVecsFromDateIndex, - pub indexes_to_supply_in_loss_rel_to_own_supply: ComputedVecsFromDateIndex, + pub indexes_to_supply_in_profit_rel_to_own_supply: + LazyVecsFrom2FromDateIndex, + pub indexes_to_supply_in_loss_rel_to_own_supply: + LazyVecsFrom2FromDateIndex, // === Supply in Profit/Loss Relative to Circulating Supply === pub height_to_supply_in_profit_rel_to_circulating_supply: @@ -60,15 +63,15 @@ pub struct RelativeMetrics { pub height_to_net_unrealized_pnl_rel_to_own_market_cap: Option>>, pub indexes_to_unrealized_profit_rel_to_own_market_cap: - Option>, + Option>, pub indexes_to_unrealized_loss_rel_to_own_market_cap: - Option>, + Option>, pub indexes_to_neg_unrealized_loss_rel_to_own_market_cap: - Option>, + Option>, pub indexes_to_net_unrealized_pnl_rel_to_own_market_cap: - Option>, + Option>, - // === Unrealized vs Own Total Unrealized PnL (optional, lazy from unrealized sources) === + // === Unrealized vs Own Total Unrealized PnL (optional) === pub height_to_unrealized_profit_rel_to_own_total_unrealized_pnl: Option>, pub height_to_unrealized_loss_rel_to_own_total_unrealized_pnl: @@ -89,7 +92,11 @@ pub struct RelativeMetrics { impl RelativeMetrics { /// Import relative metrics from database. - pub fn forced_import(cfg: &ImportConfig, unrealized: &UnrealizedMetrics) -> Result { + pub fn forced_import( + cfg: &ImportConfig, + unrealized: &UnrealizedMetrics, + supply: &SupplyMetrics, + ) -> Result { let v0 = Version::ZERO; let v1 = Version::ONE; let v2 = Version::new(2); @@ -156,33 +163,6 @@ impl RelativeMetrics { ) }); - let indexes_to_unrealized_loss_rel_to_own_market_cap: Option< - ComputedVecsFromDateIndex, - > = (extended && compute_rel_to_all) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - cfg.db, - &cfg.name("unrealized_loss_rel_to_own_market_cap"), - Source::Compute, - cfg.version + v2, - cfg.indexes, - last, - ) - }) - .transpose()?; - - let indexes_to_neg_unrealized_loss_rel_to_own_market_cap = - indexes_to_unrealized_loss_rel_to_own_market_cap - .as_ref() - .map(|source| { - LazyVecsFromDateIndex::from_computed::( - &cfg.name("neg_unrealized_loss_rel_to_own_market_cap"), - cfg.version + v2, - source.dateindex.as_ref().map(|v| v.boxed_clone()), - source, - ) - }); - // Optional: own total unrealized pnl vecs (lazy from unrealized sources) let height_to_unrealized_profit_rel_to_own_total_unrealized_pnl = extended.then(|| { LazyVecFrom2::transformed::( @@ -283,22 +263,20 @@ impl RelativeMetrics { cfg.version + v1, )?, indexes_to_supply_in_profit_rel_to_own_supply: - ComputedVecsFromDateIndex::forced_import( - cfg.db, + LazyVecsFrom2FromDateIndex::from_computed::( &cfg.name("supply_in_profit_rel_to_own_supply"), - Source::Compute, cfg.version + v1, - cfg.indexes, - last, - )?, - indexes_to_supply_in_loss_rel_to_own_supply: ComputedVecsFromDateIndex::forced_import( - cfg.db, + &unrealized.indexes_to_supply_in_profit.sats, + &supply.indexes_to_supply.sats, + ), + indexes_to_supply_in_loss_rel_to_own_supply: LazyVecsFrom2FromDateIndex::from_computed::< + PercentageSatsF64, + >( &cfg.name("supply_in_loss_rel_to_own_supply"), - Source::Compute, cfg.version + v1, - cfg.indexes, - last, - )?, + &unrealized.indexes_to_supply_in_loss.sats, + &supply.indexes_to_supply.sats, + ), // === Supply in Profit/Loss Relative to Circulating Supply === height_to_supply_in_profit_rel_to_circulating_supply: compute_rel_to_all @@ -401,30 +379,68 @@ impl RelativeMetrics { .transpose()?, indexes_to_unrealized_profit_rel_to_own_market_cap: (extended && compute_rel_to_all) .then(|| { - ComputedVecsFromDateIndex::forced_import( - cfg.db, - &cfg.name("unrealized_profit_rel_to_own_market_cap"), - Source::Compute, - cfg.version + v2, - cfg.indexes, - last, - ) + supply + .indexes_to_supply + .dollars + .as_ref() + .map(|supply_dollars| { + LazyVecsFrom2FromDateIndex::from_computed::( + &cfg.name("unrealized_profit_rel_to_own_market_cap"), + cfg.version + v2, + &unrealized.indexes_to_unrealized_profit, + supply_dollars, + ) + }) }) - .transpose()?, - indexes_to_unrealized_loss_rel_to_own_market_cap, - indexes_to_neg_unrealized_loss_rel_to_own_market_cap, + .flatten(), + indexes_to_unrealized_loss_rel_to_own_market_cap: (extended && compute_rel_to_all) + .then(|| { + supply + .indexes_to_supply + .dollars + .as_ref() + .map(|supply_dollars| { + LazyVecsFrom2FromDateIndex::from_computed::( + &cfg.name("unrealized_loss_rel_to_own_market_cap"), + cfg.version + v2, + &unrealized.indexes_to_unrealized_loss, + supply_dollars, + ) + }) + }) + .flatten(), + indexes_to_neg_unrealized_loss_rel_to_own_market_cap: (extended && compute_rel_to_all) + .then(|| { + supply + .indexes_to_supply + .dollars + .as_ref() + .map(|supply_dollars| { + LazyVecsFrom2FromDateIndex::from_computed::( + &cfg.name("neg_unrealized_loss_rel_to_own_market_cap"), + cfg.version + v2, + &unrealized.indexes_to_unrealized_loss, + supply_dollars, + ) + }) + }) + .flatten(), indexes_to_net_unrealized_pnl_rel_to_own_market_cap: (extended && compute_rel_to_all) .then(|| { - ComputedVecsFromDateIndex::forced_import( - cfg.db, - &cfg.name("net_unrealized_pnl_rel_to_own_market_cap"), - Source::Compute, - cfg.version + v2, - cfg.indexes, - last, - ) + supply + .indexes_to_supply + .dollars + .as_ref() + .map(|supply_dollars| { + LazyVecsFrom2FromDateIndex::from_computed::( + &cfg.name("net_unrealized_pnl_rel_to_own_market_cap"), + cfg.version + v2, + &unrealized.indexes_to_net_unrealized_pnl, + supply_dollars, + ) + }) }) - .transpose()?, + .flatten(), // === Unrealized vs Own Total Unrealized PnL (optional) === height_to_unrealized_profit_rel_to_own_total_unrealized_pnl, @@ -473,6 +489,7 @@ impl RelativeMetrics { } // === Supply in Profit/Loss Relative to Own Supply === + // Note: indexes_to_* versions are now lazy (LazyVecsFrom2FromDateIndex) if let Some(unrealized) = unrealized { self.height_to_supply_in_profit_rel_to_own_supply .compute_percentage( @@ -488,46 +505,6 @@ impl RelativeMetrics { &supply.height_to_supply_value.bitcoin, exit, )?; - - self.indexes_to_supply_in_profit_rel_to_own_supply - .compute_all(starting_indexes, exit, |v| { - if let Some(dateindex_vec) = unrealized - .indexes_to_supply_in_profit - .bitcoin - .dateindex - .as_ref() - && let Some(supply_dateindex) = - supply.indexes_to_supply.bitcoin.dateindex.as_ref() - { - v.compute_percentage( - starting_indexes.dateindex, - dateindex_vec, - supply_dateindex, - exit, - )?; - } - Ok(()) - })?; - - self.indexes_to_supply_in_loss_rel_to_own_supply - .compute_all(starting_indexes, exit, |v| { - if let Some(dateindex_vec) = unrealized - .indexes_to_supply_in_loss - .bitcoin - .dateindex - .as_ref() - && let Some(supply_dateindex) = - supply.indexes_to_supply.bitcoin.dateindex.as_ref() - { - v.compute_percentage( - starting_indexes.dateindex, - dateindex_vec, - supply_dateindex, - exit, - )?; - } - Ok(()) - })?; } // === Supply in Profit/Loss Relative to Circulating Supply === @@ -667,6 +644,7 @@ impl RelativeMetrics { // === Unrealized vs Own Market Cap === // own_market_cap = supply_value.dollars + // Note: indexes_to_* versions are now lazy (LazyVecsFrom2FromDateIndex) if let Some(unrealized) = unrealized { if let Some(v) = self .height_to_unrealized_profit_rel_to_own_market_cap @@ -704,67 +682,6 @@ impl RelativeMetrics { exit, )?; } - - // indexes versions - if let Some(v) = self - .indexes_to_unrealized_profit_rel_to_own_market_cap - .as_mut() - && let Some(supply_dollars_dateindex) = supply - .indexes_to_supply - .dollars - .as_ref() - .and_then(|d| d.dateindex.as_ref()) - { - v.compute_all(starting_indexes, exit, |vec| { - vec.compute_percentage( - starting_indexes.dateindex, - &unrealized.dateindex_to_unrealized_profit, - supply_dollars_dateindex, - exit, - )?; - Ok(()) - })?; - } - if let Some(v) = self - .indexes_to_unrealized_loss_rel_to_own_market_cap - .as_mut() - && let Some(supply_dollars_dateindex) = supply - .indexes_to_supply - .dollars - .as_ref() - .and_then(|d| d.dateindex.as_ref()) - { - v.compute_all(starting_indexes, exit, |vec| { - vec.compute_percentage( - starting_indexes.dateindex, - &unrealized.dateindex_to_unrealized_loss, - supply_dollars_dateindex, - exit, - )?; - Ok(()) - })?; - } - if let Some(v) = self - .indexes_to_net_unrealized_pnl_rel_to_own_market_cap - .as_mut() - && let Some(supply_dollars_dateindex) = supply - .indexes_to_supply - .dollars - .as_ref() - .and_then(|d| d.dateindex.as_ref()) - && let Some(net_pnl_dateindex) = - unrealized.indexes_to_net_unrealized_pnl.dateindex.as_ref() - { - v.compute_all(starting_indexes, exit, |vec| { - vec.compute_percentage( - starting_indexes.dateindex, - net_pnl_dateindex, - supply_dollars_dateindex, - exit, - )?; - Ok(()) - })?; - } } Ok(()) diff --git a/crates/brk_computer/src/stateful/metrics/supply.rs b/crates/brk_computer/src/stateful/metrics/supply.rs index 01b18eb8f..e92925c43 100644 --- a/crates/brk_computer/src/stateful/metrics/supply.rs +++ b/crates/brk_computer/src/stateful/metrics/supply.rs @@ -1,6 +1,6 @@ use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Height, Sats, StoredU64, Version}; +use brk_types::{Height, Sats, StoredU64, SupplyState, Version}; use rayon::prelude::*; use vecdb::{ AnyStoredVec, AnyVec, EagerVec, Exit, GenericStoredVec, ImportableVec, IterableCloneableVec, @@ -15,7 +15,6 @@ use crate::{ LazyValueVecsFromDateIndex, Source, VecBuilderOptions, }, indexes, price, - stateful::states::SupplyState, }; use super::ImportConfig; @@ -79,13 +78,16 @@ impl SupplyMetrics { )?; // Create lazy supply_half from supply sources - let height_to_supply_half_value = - LazyHeightValueVecs::from_sources::( - &cfg.name("supply_half"), - height_to_supply.boxed_clone(), - price_source, - cfg.version + v0, - ); + let height_to_supply_half_value = LazyHeightValueVecs::from_sources::< + HalveSats, + HalveSatsToBitcoin, + HalfClosePriceTimesSats, + >( + &cfg.name("supply_half"), + height_to_supply.boxed_clone(), + price_source, + cfg.version + v0, + ); let indexes_to_supply_half = LazyValueVecsFromDateIndex::from_source::( diff --git a/crates/brk_computer/src/stateful/states/address_cohort.rs b/crates/brk_computer/src/stateful/states/address_cohort.rs index 15a9a660e..63df130fb 100644 --- a/crates/brk_computer/src/stateful/states/address_cohort.rs +++ b/crates/brk_computer/src/stateful/states/address_cohort.rs @@ -1,10 +1,10 @@ use std::path::Path; use brk_error::Result; -use brk_types::{Dollars, Height, LoadedAddressData, Sats}; +use brk_types::{Dollars, Height, LoadedAddressData, Sats, SupplyState}; use vecdb::unlikely; -use crate::stateful::states::{RealizedState, SupplyState}; +use crate::stateful::states::RealizedState; use super::CohortState; diff --git a/crates/brk_computer/src/stateful/states/block.rs b/crates/brk_computer/src/stateful/states/block.rs index b70939f74..0f35dba2e 100644 --- a/crates/brk_computer/src/stateful/states/block.rs +++ b/crates/brk_computer/src/stateful/states/block.rs @@ -1,10 +1,8 @@ use std::ops::{Add, AddAssign, SubAssign}; -use brk_types::{Dollars, Timestamp}; +use brk_types::{Dollars, SupplyState, Timestamp}; use serde::Serialize; -use super::SupplyState; - #[derive(Debug, Clone, Serialize)] pub struct BlockState { #[serde(flatten)] diff --git a/crates/brk_computer/src/stateful/states/cohort.rs b/crates/brk_computer/src/stateful/states/cohort.rs index 56f432221..0538d6b86 100644 --- a/crates/brk_computer/src/stateful/states/cohort.rs +++ b/crates/brk_computer/src/stateful/states/cohort.rs @@ -1,11 +1,11 @@ use std::path::Path; use brk_error::Result; -use brk_types::{Dollars, Height, Sats}; +use brk_types::{Dollars, Height, Sats, SupplyState}; use crate::grouped::PERCENTILES_LEN; -use super::{CachedUnrealizedState, PriceToAmount, RealizedState, SupplyState, UnrealizedState}; +use super::{CachedUnrealizedState, PriceToAmount, RealizedState, UnrealizedState}; /// State tracked for each cohort during computation. #[derive(Clone)] diff --git a/crates/brk_computer/src/stateful/states/mod.rs b/crates/brk_computer/src/stateful/states/mod.rs index 0314ad2c6..716bf12a1 100644 --- a/crates/brk_computer/src/stateful/states/mod.rs +++ b/crates/brk_computer/src/stateful/states/mod.rs @@ -3,7 +3,6 @@ mod block; mod cohort; mod price_to_amount; mod realized; -mod supply; mod transacted; mod unrealized; mod utxo_cohort; @@ -13,7 +12,6 @@ pub use block::*; pub use cohort::*; pub use price_to_amount::*; pub use realized::*; -pub use supply::*; pub use transacted::*; pub use unrealized::*; pub use utxo_cohort::*; diff --git a/crates/brk_computer/src/stateful/states/price_to_amount.rs b/crates/brk_computer/src/stateful/states/price_to_amount.rs index a8e5b8091..9f0840964 100644 --- a/crates/brk_computer/src/stateful/states/price_to_amount.rs +++ b/crates/brk_computer/src/stateful/states/price_to_amount.rs @@ -6,7 +6,7 @@ use std::{ }; use brk_error::{Error, Result}; -use brk_types::{CentsCompact, Dollars, Height, Sats}; +use brk_types::{CentsCompact, Dollars, Height, Sats, SupplyState}; use derive_deref::{Deref, DerefMut}; use pco::standalone::{simple_decompress, simpler_compress}; use rustc_hash::FxHashMap; @@ -18,8 +18,6 @@ use crate::{ utils::OptionExt, }; -use super::SupplyState; - #[derive(Clone, Debug)] pub struct PriceToAmount { pathbuf: PathBuf, diff --git a/crates/brk_computer/src/stateful/states/realized.rs b/crates/brk_computer/src/stateful/states/realized.rs index 4ea5caace..264d1a35e 100644 --- a/crates/brk_computer/src/stateful/states/realized.rs +++ b/crates/brk_computer/src/stateful/states/realized.rs @@ -1,8 +1,6 @@ use std::cmp::Ordering; -use brk_types::{CheckedSub, Dollars}; - -use super::SupplyState; +use brk_types::{CheckedSub, Dollars, SupplyState}; #[derive(Debug, Default, Clone)] pub struct RealizedState { diff --git a/crates/brk_computer/src/stateful/states/transacted.rs b/crates/brk_computer/src/stateful/states/transacted.rs index caf234db9..9f4d7a184 100644 --- a/crates/brk_computer/src/stateful/states/transacted.rs +++ b/crates/brk_computer/src/stateful/states/transacted.rs @@ -1,9 +1,7 @@ use std::ops::{Add, AddAssign}; use brk_grouper::{ByAmountRange, GroupedByType}; -use brk_types::{OutputType, Sats}; - -use super::SupplyState; +use brk_types::{OutputType, Sats, SupplyState}; #[derive(Default, Debug)] pub struct Transacted { diff --git a/crates/brk_computer/src/stateful/states/utxo_cohort.rs b/crates/brk_computer/src/stateful/states/utxo_cohort.rs index 2b2c3e1e5..a301f272b 100644 --- a/crates/brk_computer/src/stateful/states/utxo_cohort.rs +++ b/crates/brk_computer/src/stateful/states/utxo_cohort.rs @@ -1,10 +1,10 @@ use std::path::Path; use brk_error::Result; -use brk_types::Sats; +use brk_types::{Sats, SupplyState}; use derive_deref::{Deref, DerefMut}; -use super::{CohortState, RealizedState, SupplyState}; +use super::{CohortState, RealizedState}; #[derive(Clone, Deref, DerefMut)] pub struct UTXOCohortState(CohortState); diff --git a/crates/brk_computer/src/stateful/vecs.rs b/crates/brk_computer/src/stateful/vecs.rs index 3664d2aaf..6b8d31772 100644 --- a/crates/brk_computer/src/stateful/vecs.rs +++ b/crates/brk_computer/src/stateful/vecs.rs @@ -5,7 +5,7 @@ use brk_indexer::Indexer; use brk_traversable::Traversable; use brk_types::{ Dollars, EmptyAddressData, EmptyAddressIndex, Height, LoadedAddressData, LoadedAddressIndex, - Sats, StoredU64, Version, + Sats, StoredU64, SupplyState, Version, }; use log::info; use vecdb::{ @@ -29,7 +29,7 @@ use crate::{ }; use super::{ - AddressCohorts, AddressesDataVecs, AnyAddressIndexesVecs, SupplyState, UTXOCohorts, + AddressCohorts, AddressesDataVecs, AnyAddressIndexesVecs, UTXOCohorts, address::{AddressTypeToHeightToAddressCount, AddressTypeToIndexesToAddressCount}, compute::aggregates, }; diff --git a/crates/brk_query/src/vecs.rs b/crates/brk_query/src/vecs.rs index e91d0370a..29bf4188c 100644 --- a/crates/brk_query/src/vecs.rs +++ b/crates/brk_query/src/vecs.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::{borrow::Cow, collections::BTreeMap}; use brk_computer::Computer; use brk_indexer::Indexer; @@ -73,7 +73,11 @@ impl<'a> Vecs<'a> { .keys() .map(|i| IndexInfo { index: *i, - aliases: i.possible_values(), + aliases: i + .possible_values() + .iter() + .map(|v| Cow::Borrowed(*v)) + .collect(), }) .collect(); @@ -116,14 +120,20 @@ impl<'a> Vecs<'a> { .entry(name) .or_default() .insert(index, vec); - assert!(prev.is_none(), "Duplicate metric: {name} for index {index:?}"); + assert!( + prev.is_none(), + "Duplicate metric: {name} for index {index:?}" + ); let prev = self .index_to_metric_to_vec .entry(index) .or_default() .insert(name, vec); - assert!(prev.is_none(), "Duplicate metric: {name} for index {index:?}"); + assert!( + prev.is_none(), + "Duplicate metric: {name} for index {index:?}" + ); } pub fn metrics(&'static self, pagination: Pagination) -> PaginatedMetrics { @@ -134,7 +144,10 @@ impl<'a> Vecs<'a> { PaginatedMetrics { current_page: pagination.page(), max_page: len.div_ceil(Pagination::PER_PAGE).saturating_sub(1), - metrics: &self.metrics[start..end], + metrics: self.metrics[start..end] + .iter() + .map(|&s| Cow::Borrowed(s)) + .collect(), } } diff --git a/crates/brk_server/src/api/mod.rs b/crates/brk_server/src/api/mod.rs index f9458cb88..e9021f795 100644 --- a/crates/brk_server/src/api/mod.rs +++ b/crates/brk_server/src/api/mod.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{borrow::Cow, sync::Arc}; use aide::{ axum::{ApiRouter, routing::get_with}, @@ -71,8 +71,8 @@ impl ApiRoutes for ApiRouter { get_with( async || -> Json { Json(Health { - status: "healthy", - service: "brk", + status: Cow::Borrowed("healthy"), + service: Cow::Borrowed("brk"), timestamp: jiff::Timestamp::now().to_string(), }) }, diff --git a/crates/brk_types/src/blkposition.rs b/crates/brk_types/src/blkposition.rs index 4fa08ab02..0fb56884a 100644 --- a/crates/brk_types/src/blkposition.rs +++ b/crates/brk_types/src/blkposition.rs @@ -1,11 +1,11 @@ use std::ops::Add; use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use vecdb::{Formattable, Pco}; /// Position within a .blk file, encoding file index and byte offset -#[derive(Debug, Clone, Copy, Serialize, Pco, JsonSchema)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, Pco, JsonSchema)] pub struct BlkPosition(u64); impl BlkPosition { diff --git a/crates/brk_types/src/blockfeesentry.rs b/crates/brk_types/src/blockfeesentry.rs index 9f2323e19..6e2590a0d 100644 --- a/crates/brk_types/src/blockfeesentry.rs +++ b/crates/brk_types/src/blockfeesentry.rs @@ -1,10 +1,10 @@ use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::{Height, Sats, Timestamp}; /// A single block fees data point. -#[derive(Debug, Serialize, JsonSchema)] +#[derive(Debug, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "camelCase")] pub struct BlockFeesEntry { pub avg_height: Height, diff --git a/crates/brk_types/src/difficultyadjustment.rs b/crates/brk_types/src/difficultyadjustment.rs index 97ace9760..edba7a7eb 100644 --- a/crates/brk_types/src/difficultyadjustment.rs +++ b/crates/brk_types/src/difficultyadjustment.rs @@ -1,10 +1,10 @@ use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::Height; /// Difficulty adjustment information. -#[derive(Debug, Clone, Serialize, JsonSchema)] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "camelCase")] pub struct DifficultyAdjustment { /// Progress through current difficulty epoch (0-100%) diff --git a/crates/brk_types/src/health.rs b/crates/brk_types/src/health.rs index 0844630de..baad986aa 100644 --- a/crates/brk_types/src/health.rs +++ b/crates/brk_types/src/health.rs @@ -1,10 +1,12 @@ +use std::borrow::Cow; + use schemars::JsonSchema; use serde::{Deserialize, Serialize}; /// Server health status #[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct Health { - pub status: &'static str, - pub service: &'static str, + pub status: Cow<'static, str>, + pub service: Cow<'static, str>, pub timestamp: String, } diff --git a/crates/brk_types/src/hex.rs b/crates/brk_types/src/hex.rs index 38fb6ebf1..6848de80a 100644 --- a/crates/brk_types/src/hex.rs +++ b/crates/brk_types/src/hex.rs @@ -1,7 +1,7 @@ use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; /// Hex-encoded string -#[derive(Debug, Clone, Serialize, JsonSchema)] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] #[serde(transparent)] pub struct Hex(String); diff --git a/crates/brk_types/src/indexinfo.rs b/crates/brk_types/src/indexinfo.rs index 65db2b586..34078a3f4 100644 --- a/crates/brk_types/src/indexinfo.rs +++ b/crates/brk_types/src/indexinfo.rs @@ -1,15 +1,17 @@ +use std::borrow::Cow; + use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use super::Index; /// Information about an available index and its query aliases -#[derive(Clone, Copy, Serialize, JsonSchema)] +#[derive(Clone, Serialize, Deserialize, JsonSchema)] pub struct IndexInfo { /// The canonical index name pub index: Index, /// All Accepted query aliases #[schemars(example = vec!["d", "date", "dateindex"])] - pub aliases: &'static [&'static str], + pub aliases: Vec>, } diff --git a/crates/brk_types/src/lib.rs b/crates/brk_types/src/lib.rs index 2b35ff09d..ea6f1176b 100644 --- a/crates/brk_types/src/lib.rs +++ b/crates/brk_types/src/lib.rs @@ -125,6 +125,7 @@ mod stored_u16; mod stored_u32; mod stored_u64; mod stored_u8; +mod supply_state; mod timeperiod; mod timeperiodparam; mod timestamp; @@ -280,6 +281,7 @@ pub use stored_u8::*; pub use stored_u16::*; pub use stored_u32::*; pub use stored_u64::*; +pub use supply_state::*; pub use timeperiod::*; pub use timeperiodparam::*; pub use timestamp::*; diff --git a/crates/brk_types/src/mempoolblock.rs b/crates/brk_types/src/mempoolblock.rs index 277c18987..ff86837c7 100644 --- a/crates/brk_types/src/mempoolblock.rs +++ b/crates/brk_types/src/mempoolblock.rs @@ -1,10 +1,10 @@ use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::{FeeRate, Sats, VSize}; /// Block info in a mempool.space like format for fee estimation. -#[derive(Debug, Clone, Serialize, JsonSchema)] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "camelCase")] pub struct MempoolBlock { /// Total block size in weight units diff --git a/crates/brk_types/src/metricspaginated.rs b/crates/brk_types/src/metricspaginated.rs index 4836a8986..93609c426 100644 --- a/crates/brk_types/src/metricspaginated.rs +++ b/crates/brk_types/src/metricspaginated.rs @@ -1,8 +1,10 @@ +use std::borrow::Cow; + use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; /// A paginated list of available metric names (1000 per page) -#[derive(Debug, Serialize, JsonSchema)] +#[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct PaginatedMetrics { /// Current page number (0-indexed) #[schemars(example = 0)] @@ -11,5 +13,5 @@ pub struct PaginatedMetrics { #[schemars(example = 21)] pub max_page: usize, /// List of metric names (max 1000 per page) - pub metrics: &'static [&'static str], + pub metrics: Vec>, } diff --git a/crates/brk_types/src/pooldetail.rs b/crates/brk_types/src/pooldetail.rs index f4ce632a0..981025406 100644 --- a/crates/brk_types/src/pooldetail.rs +++ b/crates/brk_types/src/pooldetail.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use crate::{Pool, PoolSlug}; /// Detailed pool information with statistics across time periods -#[derive(Debug, Serialize, JsonSchema)] +#[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct PoolDetail { /// Pool information pub pool: PoolDetailInfo, @@ -29,22 +29,22 @@ pub struct PoolDetail { } /// Pool information for detail view -#[derive(Debug, Serialize, JsonSchema)] +#[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct PoolDetailInfo { /// Unique pool identifier pub id: u8, /// Pool name - pub name: &'static str, + pub name: Cow<'static, str>, /// Pool website URL - pub link: &'static str, + pub link: Cow<'static, str>, /// Known payout addresses - pub addresses: Vec<&'static str>, + pub addresses: Vec>, /// Coinbase tag patterns (regexes) - pub regexes: Vec<&'static str>, + pub regexes: Vec>, /// URL-friendly pool identifier pub slug: PoolSlug, @@ -54,10 +54,10 @@ impl From<&'static Pool> for PoolDetailInfo { fn from(pool: &'static Pool) -> Self { Self { id: pool.unique_id(), - name: pool.name, - link: pool.link, - addresses: pool.addresses.to_vec(), - regexes: pool.tags.to_vec(), + name: Cow::Borrowed(pool.name), + link: Cow::Borrowed(pool.link), + addresses: pool.addresses.iter().map(|&s| Cow::Borrowed(s)).collect(), + regexes: pool.tags.iter().map(|&s| Cow::Borrowed(s)).collect(), slug: pool.slug(), } } diff --git a/crates/brk_types/src/poolinfo.rs b/crates/brk_types/src/poolinfo.rs index bb15b5563..0523be85e 100644 --- a/crates/brk_types/src/poolinfo.rs +++ b/crates/brk_types/src/poolinfo.rs @@ -1,13 +1,15 @@ +use std::borrow::Cow; + use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::{Pool, PoolSlug}; /// Basic pool information for listing all pools -#[derive(Debug, Serialize, JsonSchema)] +#[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct PoolInfo { /// Pool name - pub name: &'static str, + pub name: Cow<'static, str>, /// URL-friendly pool identifier pub slug: PoolSlug, @@ -19,7 +21,7 @@ pub struct PoolInfo { impl From<&'static Pool> for PoolInfo { fn from(pool: &'static Pool) -> Self { Self { - name: pool.name, + name: Cow::Borrowed(pool.name), slug: pool.slug(), unique_id: pool.unique_id(), } diff --git a/crates/brk_types/src/poolssummary.rs b/crates/brk_types/src/poolssummary.rs index 32b44061b..bd3fa0180 100644 --- a/crates/brk_types/src/poolssummary.rs +++ b/crates/brk_types/src/poolssummary.rs @@ -1,10 +1,10 @@ use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::PoolStats; /// Mining pools response for a time period -#[derive(Debug, Serialize, JsonSchema)] +#[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct PoolsSummary { /// List of pools sorted by block count descending pub pools: Vec, diff --git a/crates/brk_types/src/poolstats.rs b/crates/brk_types/src/poolstats.rs index 1e52d0a3d..0994104fe 100644 --- a/crates/brk_types/src/poolstats.rs +++ b/crates/brk_types/src/poolstats.rs @@ -1,20 +1,22 @@ +use std::borrow::Cow; + use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::{Pool, PoolSlug}; /// Mining pool with block statistics for a time period -#[derive(Debug, Serialize, JsonSchema)] +#[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct PoolStats { /// Unique pool identifier #[serde(rename = "poolId")] pub pool_id: u8, /// Pool name - pub name: &'static str, + pub name: Cow<'static, str>, /// Pool website URL - pub link: &'static str, + pub link: Cow<'static, str>, /// Number of blocks mined in the time period #[serde(rename = "blockCount")] @@ -39,8 +41,8 @@ impl PoolStats { pub fn new(pool: &'static Pool, block_count: u32, rank: u32, share: f64) -> Self { Self { pool_id: pool.unique_id(), - name: pool.name, - link: pool.link, + name: Cow::Borrowed(pool.name), + link: Cow::Borrowed(pool.link), block_count, rank, empty_blocks: 0, // TODO: track empty blocks if needed diff --git a/crates/brk_types/src/recommendedfees.rs b/crates/brk_types/src/recommendedfees.rs index 4b7e51b73..20414c2d8 100644 --- a/crates/brk_types/src/recommendedfees.rs +++ b/crates/brk_types/src/recommendedfees.rs @@ -1,10 +1,10 @@ use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::FeeRate; /// Recommended fee rates in sat/vB -#[derive(Debug, Default, Clone, Serialize, JsonSchema)] +#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "camelCase")] pub struct RecommendedFees { /// Fee rate for fastest confirmation (next block) diff --git a/crates/brk_computer/src/stateful/states/supply.rs b/crates/brk_types/src/supply_state.rs similarity index 93% rename from crates/brk_computer/src/stateful/states/supply.rs rename to crates/brk_types/src/supply_state.rs index 1a3794861..2e50cc158 100644 --- a/crates/brk_computer/src/stateful/states/supply.rs +++ b/crates/brk_types/src/supply_state.rs @@ -1,10 +1,14 @@ -use std::ops::{Add, AddAssign, SubAssign}; +use std::{ + fmt, + ops::{Add, AddAssign, SubAssign}, +}; -use brk_types::{CheckedSub, LoadedAddressData, Sats}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use vecdb::{Bytes, Formattable}; +use crate::{CheckedSub, LoadedAddressData, Sats}; + /// Current supply state tracking UTXO count and total value #[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)] pub struct SupplyState { @@ -71,8 +75,8 @@ impl From<&LoadedAddressData> for SupplyState { } } -impl std::fmt::Display for SupplyState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Display for SupplyState { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "utxos: {}, value: {}", self.utxo_count, self.value) } } diff --git a/crates/brk_types/src/txoutspend.rs b/crates/brk_types/src/txoutspend.rs index 73fa41c99..aa1eb2303 100644 --- a/crates/brk_types/src/txoutspend.rs +++ b/crates/brk_types/src/txoutspend.rs @@ -1,10 +1,10 @@ use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::{TxStatus, Txid, Vin}; /// Status of an output indicating whether it has been spent -#[derive(Debug, Clone, Serialize, JsonSchema)] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] pub struct TxOutspend { /// Whether the output has been spent pub spent: bool, diff --git a/crates/brk_types/src/vin.rs b/crates/brk_types/src/vin.rs index 3b7f287e5..56f0bd4ba 100644 --- a/crates/brk_types/src/vin.rs +++ b/crates/brk_types/src/vin.rs @@ -1,9 +1,11 @@ use derive_deref::Deref; use schemars::JsonSchema; -use serde::Serialize; +use serde::{Deserialize, Serialize}; /// Input index in the spending transaction -#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, JsonSchema)] +#[derive( + Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema, +)] #[schemars(example = 0)] pub struct Vin(u16); diff --git a/modules/lightweight-charts/5.0.9/dist/typings.d.ts b/modules/lightweight-charts/5.0.9/dist/typings.d.ts index 5c6b68252..a77c8077d 100644 --- a/modules/lightweight-charts/5.0.9/dist/typings.d.ts +++ b/modules/lightweight-charts/5.0.9/dist/typings.d.ts @@ -1,6 +1,6 @@ // Generated by dts-bundle-generator v9.5.1 -import { CanvasRenderingTarget2D } from 'fancy-canvas'; +type CanvasRenderingTarget2D = any; declare const areaSeries: SeriesDefinition<"Area">; declare const barSeries: SeriesDefinition<"Bar">; @@ -13,178 +13,178 @@ export declare const customSeriesDefaultOptions: CustomSeriesOptions; * Enumeration representing the sign of a marker. */ export declare const enum MarkerSign { - /** Represents a negative change (-1) */ - Negative = -1, - /** Represents no change (0) */ - Neutral = 0, - /** Represents a positive change (1) */ - Positive = 1 + /** Represents a negative change (-1) */ + Negative = -1, + /** Represents no change (0) */ + Neutral = 0, + /** Represents a positive change (1) */ + Positive = 1, } /** * Represents a type of color. */ export declare enum ColorType { - /** Solid color */ - Solid = "solid", - /** Vertical gradient color */ - VerticalGradient = "gradient" + /** Solid color */ + Solid = "solid", + /** Vertical gradient color */ + VerticalGradient = "gradient", } /** * Represents the crosshair mode. */ export declare enum CrosshairMode { - /** - * This mode allows crosshair to move freely on the chart. - */ - Normal = 0, - /** - * This mode sticks crosshair's horizontal line to the price value of a single-value series or to the close price of OHLC-based series. - */ - Magnet = 1, - /** - * This mode disables rendering of the crosshair. - */ - Hidden = 2, - /** - * This mode sticks crosshair's horizontal line to the price value of a single-value series or to the open/high/low/close price of OHLC-based series. - */ - MagnetOHLC = 3 + /** + * This mode allows crosshair to move freely on the chart. + */ + Normal = 0, + /** + * This mode sticks crosshair's horizontal line to the price value of a single-value series or to the close price of OHLC-based series. + */ + Magnet = 1, + /** + * This mode disables rendering of the crosshair. + */ + Hidden = 2, + /** + * This mode sticks crosshair's horizontal line to the price value of a single-value series or to the open/high/low/close price of OHLC-based series. + */ + MagnetOHLC = 3, } /** * Represents the type of the last price animation for series such as area or line. */ export declare enum LastPriceAnimationMode { - /** - * Animation is always disabled - */ - Disabled = 0, - /** - * Animation is always enabled. - */ - Continuous = 1, - /** - * Animation is active after new data. - */ - OnDataUpdate = 2 + /** + * Animation is always disabled + */ + Disabled = 0, + /** + * Animation is always enabled. + */ + Continuous = 1, + /** + * Animation is active after new data. + */ + OnDataUpdate = 2, } /** * Represents the possible line styles. */ export declare enum LineStyle { - /** - * A solid line. - */ - Solid = 0, - /** - * A dotted line. - */ - Dotted = 1, - /** - * A dashed line. - */ - Dashed = 2, - /** - * A dashed line with bigger dashes. - */ - LargeDashed = 3, - /** - * A dotted line with more space between dots. - */ - SparseDotted = 4 + /** + * A solid line. + */ + Solid = 0, + /** + * A dotted line. + */ + Dotted = 1, + /** + * A dashed line. + */ + Dashed = 2, + /** + * A dashed line with bigger dashes. + */ + LargeDashed = 3, + /** + * A dotted line with more space between dots. + */ + SparseDotted = 4, } /** * Represents the possible line types. */ export declare enum LineType { - /** - * A line. - */ - Simple = 0, - /** - * A stepped line. - */ - WithSteps = 1, - /** - * A curved line. - */ - Curved = 2 + /** + * A line. + */ + Simple = 0, + /** + * A stepped line. + */ + WithSteps = 1, + /** + * A curved line. + */ + Curved = 2, } /** * Search direction if no data found at provided index */ export declare enum MismatchDirection { - /** - * Search the nearest left item - */ - NearestLeft = -1, - /** - * Do not search - */ - None = 0, - /** - * Search the nearest right item - */ - NearestRight = 1 + /** + * Search the nearest left item + */ + NearestLeft = -1, + /** + * Do not search + */ + None = 0, + /** + * Search the nearest right item + */ + NearestRight = 1, } /** * Represents the source of data to be used for the horizontal price line. */ export declare enum PriceLineSource { - /** - * Use the last bar data. - */ - LastBar = 0, - /** - * Use the last visible data of the chart viewport. - */ - LastVisible = 1 + /** + * Use the last bar data. + */ + LastBar = 0, + /** + * Use the last visible data of the chart viewport. + */ + LastVisible = 1, } /** * Represents the price scale mode. */ export declare enum PriceScaleMode { - /** - * Price scale shows prices. Price range changes linearly. - */ - Normal = 0, - /** - * Price scale shows prices. Price range changes logarithmically. - */ - Logarithmic = 1, - /** - * Price scale shows percentage values according the first visible value of the price scale. - * The first visible value is 0% in this mode. - */ - Percentage = 2, - /** - * The same as percentage mode, but the first value is moved to 100. - */ - IndexedTo100 = 3 + /** + * Price scale shows prices. Price range changes linearly. + */ + Normal = 0, + /** + * Price scale shows prices. Price range changes logarithmically. + */ + Logarithmic = 1, + /** + * Price scale shows percentage values according the first visible value of the price scale. + * The first visible value is 0% in this mode. + */ + Percentage = 2, + /** + * The same as percentage mode, but the first value is moved to 100. + */ + IndexedTo100 = 3, } /** * Represents the type of a tick mark on the time axis. */ export declare enum TickMarkType { - /** - * The start of the year (e.g. it's the first tick mark in a year). - */ - Year = 0, - /** - * The start of the month (e.g. it's the first tick mark in a month). - */ - Month = 1, - /** - * A day of the month. - */ - DayOfMonth = 2, - /** - * A time without seconds. - */ - Time = 3, - /** - * A time with seconds. - */ - TimeWithSeconds = 4 + /** + * The start of the year (e.g. it's the first tick mark in a year). + */ + Year = 0, + /** + * The start of the month (e.g. it's the first tick mark in a month). + */ + Month = 1, + /** + * A day of the month. + */ + DayOfMonth = 2, + /** + * A time without seconds. + */ + Time = 3, + /** + * A time with seconds. + */ + TimeWithSeconds = 4, } /** * Determine how to exit the tracking mode. @@ -193,14 +193,14 @@ export declare enum TickMarkType { * Another press is required to activate the scroll, be able to move left/right, zoom, etc. */ export declare enum TrackingModeExitMode { - /** - * Tracking Mode will be deactivated on touch end event. - */ - OnTouchEnd = 0, - /** - * Tracking Mode will be deactivated on the next tap event. - */ - OnNextTap = 1 + /** + * Tracking Mode will be deactivated on touch end event. + */ + OnTouchEnd = 0, + /** + * Tracking Mode will be deactivated on the next tap event. + */ + OnNextTap = 1, } /** * This function is the simplified main entry point of the Lightweight Charting Library with time points for the horizontal scale. @@ -209,7 +209,10 @@ export declare enum TrackingModeExitMode { * @param options - Any subset of options to be applied at start. * @returns An interface to the created chart */ -export declare function createChart(container: string | HTMLElement, options?: DeepPartial): IChartApi; +export declare function createChart( + container: string | HTMLElement, + options?: DeepPartial, +): IChartApi; /** * This function is the main entry point of the Lightweight Charting Library. If you are using time values * for the horizontal scale then it is recommended that you rather use the {@link createChart} function. @@ -222,7 +225,14 @@ export declare function createChart(container: string | HTMLElement, options?: D * @param options - Any subset of options to be applied at start. * @returns An interface to the created chart */ -export declare function createChartEx>(container: string | HTMLElement, horzScaleBehavior: THorzScaleBehavior, options?: DeepPartial>): IChartApiBase; +export declare function createChartEx< + HorzScaleItem, + THorzScaleBehavior extends IHorzScaleBehavior, +>( + container: string | HTMLElement, + horzScaleBehavior: THorzScaleBehavior, + options?: DeepPartial>, +): IChartApiBase; /** * Creates an image watermark. * @@ -247,7 +257,11 @@ export declare function createChartEx(pane: IPaneApi, imageUrl: string, options: DeepPartial): IImageWatermarkPluginApi; +export declare function createImageWatermark( + pane: IPaneApi, + imageUrl: string, + options: DeepPartial, +): IImageWatermarkPluginApi; /** * Creates an 'options' chart with price values on the horizontal scale. * @@ -259,7 +273,10 @@ export declare function createImageWatermark(pane: IPaneApi, imageUrl: str * @param options - Optional configuration options for the price chart. * @returns An instance of IChartApiBase configured for price-based horizontal scaling. */ -export declare function createOptionsChart(container: string | HTMLElement, options?: DeepPartial): IChartApiBase; +export declare function createOptionsChart( + container: string | HTMLElement, + options?: DeepPartial, +): IChartApiBase; /** * A function to create a series markers primitive. * @@ -291,7 +308,11 @@ export declare function createOptionsChart(container: string | HTMLElement, opti * // `seriesMarkers.markers()` returns current markers * ``` */ -export declare function createSeriesMarkers(series: ISeriesApi, markers?: SeriesMarker[], options?: DeepPartial): ISeriesMarkersPluginApi; +export declare function createSeriesMarkers( + series: ISeriesApi, + markers?: SeriesMarker[], + options?: DeepPartial, +): ISeriesMarkersPluginApi; /** * Creates an image watermark. * @@ -330,7 +351,10 @@ export declare function createSeriesMarkers(series: ISeriesApi(pane: IPaneApi, options: DeepPartial): ITextWatermarkPluginApi; +export declare function createTextWatermark( + pane: IPaneApi, + options: DeepPartial, +): ITextWatermarkPluginApi; /** * Creates and attaches the Series Up Down Markers Plugin. * @@ -363,7 +387,10 @@ export declare function createTextWatermark(pane: IPaneApi, options: DeepP * upDownMarkers.detach(); * ``` */ -export declare function createUpDownMarkers(series: ISeriesApi, options?: Partial): ISeriesUpDownMarkerPluginApi; +export declare function createUpDownMarkers( + series: ISeriesApi, + options?: Partial, +): ISeriesUpDownMarkerPluginApi; /** * Creates a yield curve chart with the specified options. * @@ -377,7 +404,10 @@ export declare function createUpDownMarkers(series: ISeriesApi * @param options - The yield chart options. * @returns An interface to the created chart */ -export declare function createYieldCurveChart(container: string | HTMLElement, options?: DeepPartial): IYieldCurveChartApi; +export declare function createYieldCurveChart( + container: string | HTMLElement, + options?: DeepPartial, +): IYieldCurveChartApi; /** * Provides the default implementation of the horizontal scale (time-based) that can be used as a base for extending the horizontal scale with custom behavior. * This allows for the introduction of custom functionality without re-implementing the entire {@link IHorzScaleBehavior}<{@link Time}> interface. @@ -408,406 +438,409 @@ export declare function version(): string; /** * Structure describing a single item of data for area series */ -export interface AreaData extends SingleValueData { - /** - * Optional line color value for certain data item. If missed, color from options is used - */ - lineColor?: string; - /** - * Optional top color value for certain data item. If missed, color from options is used - */ - topColor?: string; - /** - * Optional bottom color value for certain data item. If missed, color from options is used - */ - bottomColor?: string; +export interface AreaData + extends SingleValueData { + /** + * Optional line color value for certain data item. If missed, color from options is used + */ + lineColor?: string; + /** + * Optional top color value for certain data item. If missed, color from options is used + */ + topColor?: string; + /** + * Optional bottom color value for certain data item. If missed, color from options is used + */ + bottomColor?: string; } /** * Represents style options for an area series. */ export interface AreaStyleOptions { - /** - * Color of the top part of the area. - * - * @defaultValue `'rgba( 46, 220, 135, 0.4)'` - */ - topColor: string; - /** - * Color of the bottom part of the area. - * - * @defaultValue `'rgba( 40, 221, 100, 0)'` - */ - bottomColor: string; - /** - * Gradient is relative to the base value and the currently visible range. - * If it is false, the gradient is relative to the top and bottom of the chart. - * - * @defaultValue `false` - */ - relativeGradient: boolean; - /** - * Invert the filled area. Fills the area above the line if set to true. - * - * @defaultValue `false` - */ - invertFilledArea: boolean; - /** - * Line color. - * - * @defaultValue `'#33D778'` - */ - lineColor: string; - /** - * Line style. - * - * @defaultValue {@link LineStyle.Solid} - */ - lineStyle: LineStyle; - /** - * Line width in pixels. - * - * @defaultValue `3` - */ - lineWidth: LineWidth; - /** - * Line type. - * - * @defaultValue {@link LineType.Simple} - */ - lineType: LineType; - /** - * Show series line. - * - * @defaultValue `true` - */ - lineVisible: boolean; - /** - * Show circle markers on each point. - * - * @defaultValue `false` - */ - pointMarkersVisible: boolean; - /** - * Circle markers radius in pixels. - * - * @defaultValue `undefined` - */ - pointMarkersRadius?: number; - /** - * Show the crosshair marker. - * - * @defaultValue `true` - */ - crosshairMarkerVisible: boolean; - /** - * Crosshair marker radius in pixels. - * - * @defaultValue `4` - */ - crosshairMarkerRadius: number; - /** - * Crosshair marker border color. An empty string falls back to the color of the series under the crosshair. - * - * @defaultValue `''` - */ - crosshairMarkerBorderColor: string; - /** - * The crosshair marker background color. An empty string falls back to the color of the series under the crosshair. - * - * @defaultValue `''` - */ - crosshairMarkerBackgroundColor: string; - /** - * Crosshair marker border width in pixels. - * - * @defaultValue `2` - */ - crosshairMarkerBorderWidth: number; - /** - * Last price animation mode. - * - * @defaultValue {@link LastPriceAnimationMode.Disabled} - */ - lastPriceAnimation: LastPriceAnimationMode; + /** + * Color of the top part of the area. + * + * @defaultValue `'rgba( 46, 220, 135, 0.4)'` + */ + topColor: string; + /** + * Color of the bottom part of the area. + * + * @defaultValue `'rgba( 40, 221, 100, 0)'` + */ + bottomColor: string; + /** + * Gradient is relative to the base value and the currently visible range. + * If it is false, the gradient is relative to the top and bottom of the chart. + * + * @defaultValue `false` + */ + relativeGradient: boolean; + /** + * Invert the filled area. Fills the area above the line if set to true. + * + * @defaultValue `false` + */ + invertFilledArea: boolean; + /** + * Line color. + * + * @defaultValue `'#33D778'` + */ + lineColor: string; + /** + * Line style. + * + * @defaultValue {@link LineStyle.Solid} + */ + lineStyle: LineStyle; + /** + * Line width in pixels. + * + * @defaultValue `3` + */ + lineWidth: LineWidth; + /** + * Line type. + * + * @defaultValue {@link LineType.Simple} + */ + lineType: LineType; + /** + * Show series line. + * + * @defaultValue `true` + */ + lineVisible: boolean; + /** + * Show circle markers on each point. + * + * @defaultValue `false` + */ + pointMarkersVisible: boolean; + /** + * Circle markers radius in pixels. + * + * @defaultValue `undefined` + */ + pointMarkersRadius?: number; + /** + * Show the crosshair marker. + * + * @defaultValue `true` + */ + crosshairMarkerVisible: boolean; + /** + * Crosshair marker radius in pixels. + * + * @defaultValue `4` + */ + crosshairMarkerRadius: number; + /** + * Crosshair marker border color. An empty string falls back to the color of the series under the crosshair. + * + * @defaultValue `''` + */ + crosshairMarkerBorderColor: string; + /** + * The crosshair marker background color. An empty string falls back to the color of the series under the crosshair. + * + * @defaultValue `''` + */ + crosshairMarkerBackgroundColor: string; + /** + * Crosshair marker border width in pixels. + * + * @defaultValue `2` + */ + crosshairMarkerBorderWidth: number; + /** + * Last price animation mode. + * + * @defaultValue {@link LastPriceAnimationMode.Disabled} + */ + lastPriceAnimation: LastPriceAnimationMode; } /** * Represents the margin used when updating a price scale. */ export interface AutoScaleMargins { - /** The number of pixels for bottom margin */ - below: number; - /** The number of pixels for top margin */ - above: number; + /** The number of pixels for bottom margin */ + below: number; + /** The number of pixels for top margin */ + above: number; } /** * Represents information used to update a price scale. */ export interface AutoscaleInfo { - /** - * Price range. - */ - priceRange: PriceRange | null; - /** - * Scale margins. - */ - margins?: AutoScaleMargins; + /** + * Price range. + */ + priceRange: PriceRange | null; + /** + * Scale margins. + */ + margins?: AutoScaleMargins; } /** * Represents options for how the time and price axes react to mouse double click. */ export interface AxisDoubleClickOptions { - /** - * Enable resetting scaling the time axis by double-clicking the left mouse button. - * - * @defaultValue `true` - */ - time: boolean; - /** - * Enable reseting scaling the price axis by by double-clicking the left mouse button. - * - * @defaultValue `true` - */ - price: boolean; + /** + * Enable resetting scaling the time axis by double-clicking the left mouse button. + * + * @defaultValue `true` + */ + time: boolean; + /** + * Enable reseting scaling the price axis by by double-clicking the left mouse button. + * + * @defaultValue `true` + */ + price: boolean; } /** * Represents options for how the time and price axes react to mouse movements. */ export interface AxisPressedMouseMoveOptions { - /** - * Enable scaling the time axis by holding down the left mouse button and moving the mouse. - * - * @defaultValue `true` - */ - time: boolean; - /** - * Enable scaling the price axis by holding down the left mouse button and moving the mouse. - * - * @defaultValue `true` - */ - price: boolean; + /** + * Enable scaling the time axis by holding down the left mouse button and moving the mouse. + * + * @defaultValue `true` + */ + time: boolean; + /** + * Enable scaling the price axis by holding down the left mouse button and moving the mouse. + * + * @defaultValue `true` + */ + price: boolean; } /** * Structure describing a single item of data for bar series */ export interface BarData extends OhlcData { - /** - * Optional color value for certain data item. If missed, color from options is used - */ - color?: string; + /** + * Optional color value for certain data item. If missed, color from options is used + */ + color?: string; } /** * Represents style options for a bar series. */ export interface BarStyleOptions { - /** - * Color of rising bars. - * - * @defaultValue `'#26a69a'` - */ - upColor: string; - /** - * Color of falling bars. - * - * @defaultValue `'#ef5350'` - */ - downColor: string; - /** - * Show open lines on bars. - * - * @defaultValue `true` - */ - openVisible: boolean; - /** - * Show bars as sticks. - * - * @defaultValue `true` - */ - thinBars: boolean; + /** + * Color of rising bars. + * + * @defaultValue `'#26a69a'` + */ + upColor: string; + /** + * Color of falling bars. + * + * @defaultValue `'#ef5350'` + */ + downColor: string; + /** + * Show open lines on bars. + * + * @defaultValue `true` + */ + openVisible: boolean; + /** + * Show bars as sticks. + * + * @defaultValue `true` + */ + thinBars: boolean; } /** * Represents a range of bars and the number of bars outside the range. */ -export interface BarsInfo extends Partial> { - /** - * The number of bars before the start of the range. - * Positive value means that there are some bars before (out of logical range from the left) the {@link IRange.from} logical index in the series. - * Negative value means that the first series' bar is inside the passed logical range, and between the first series' bar and the {@link IRange.from} logical index are some bars. - */ - barsBefore: number; - /** - * The number of bars after the end of the range. - * Positive value in the `barsAfter` field means that there are some bars after (out of logical range from the right) the {@link IRange.to} logical index in the series. - * Negative value means that the last series' bar is inside the passed logical range, and between the last series' bar and the {@link IRange.to} logical index are some bars. - */ - barsAfter: number; +export interface BarsInfo + extends Partial> { + /** + * The number of bars before the start of the range. + * Positive value means that there are some bars before (out of logical range from the left) the {@link IRange.from} logical index in the series. + * Negative value means that the first series' bar is inside the passed logical range, and between the first series' bar and the {@link IRange.from} logical index are some bars. + */ + barsBefore: number; + /** + * The number of bars after the end of the range. + * Positive value in the `barsAfter` field means that there are some bars after (out of logical range from the right) the {@link IRange.to} logical index in the series. + * Negative value means that the last series' bar is inside the passed logical range, and between the last series' bar and the {@link IRange.to} logical index are some bars. + */ + barsAfter: number; } /** * Represents a type of priced base value of baseline series type. */ export interface BaseValuePrice { - /** - * Distinguished type value. - */ - type: "price"; - /** - * Price value. - */ - price: number; + /** + * Distinguished type value. + */ + type: "price"; + /** + * Price value. + */ + price: number; } /** * Structure describing a single item of data for baseline series */ -export interface BaselineData extends SingleValueData { - /** - * Optional top area top fill color value for certain data item. If missed, color from options is used - */ - topFillColor1?: string; - /** - * Optional top area bottom fill color value for certain data item. If missed, color from options is used - */ - topFillColor2?: string; - /** - * Optional top area line color value for certain data item. If missed, color from options is used - */ - topLineColor?: string; - /** - * Optional bottom area top fill color value for certain data item. If missed, color from options is used - */ - bottomFillColor1?: string; - /** - * Optional bottom area bottom fill color value for certain data item. If missed, color from options is used - */ - bottomFillColor2?: string; - /** - * Optional bottom area line color value for certain data item. If missed, color from options is used - */ - bottomLineColor?: string; +export interface BaselineData + extends SingleValueData { + /** + * Optional top area top fill color value for certain data item. If missed, color from options is used + */ + topFillColor1?: string; + /** + * Optional top area bottom fill color value for certain data item. If missed, color from options is used + */ + topFillColor2?: string; + /** + * Optional top area line color value for certain data item. If missed, color from options is used + */ + topLineColor?: string; + /** + * Optional bottom area top fill color value for certain data item. If missed, color from options is used + */ + bottomFillColor1?: string; + /** + * Optional bottom area bottom fill color value for certain data item. If missed, color from options is used + */ + bottomFillColor2?: string; + /** + * Optional bottom area line color value for certain data item. If missed, color from options is used + */ + bottomLineColor?: string; } /** * Represents style options for a baseline series. */ export interface BaselineStyleOptions { - /** - * Base value of the series. - * - * @defaultValue `{ type: 'price', price: 0 }` - */ - baseValue: BaseValueType; - /** - * Gradient is relative to the base value and the currently visible range. - * If it is false, the gradient is relative to the top and bottom of the chart. - * - * @defaultValue `false` - */ - relativeGradient: boolean; - /** - * The first color of the top area. - * - * @defaultValue `'rgba(38, 166, 154, 0.28)'` - */ - topFillColor1: string; - /** - * The second color of the top area. - * - * @defaultValue `'rgba(38, 166, 154, 0.05)'` - */ - topFillColor2: string; - /** - * The line color of the top area. - * - * @defaultValue `'rgba(38, 166, 154, 1)'` - */ - topLineColor: string; - /** - * The first color of the bottom area. - * - * @defaultValue `'rgba(239, 83, 80, 0.05)'` - */ - bottomFillColor1: string; - /** - * The second color of the bottom area. - * - * @defaultValue `'rgba(239, 83, 80, 0.28)'` - */ - bottomFillColor2: string; - /** - * The line color of the bottom area. - * - * @defaultValue `'rgba(239, 83, 80, 1)'` - */ - bottomLineColor: string; - /** - * Line width. - * - * @defaultValue `3` - */ - lineWidth: LineWidth; - /** - * Line style. - * - * @defaultValue {@link LineStyle.Solid} - */ - lineStyle: LineStyle; - /** - * Line type. - * - * @defaultValue {@link LineType.Simple} - */ - lineType: LineType; - /** - * Show series line. - * - * @defaultValue `true` - */ - lineVisible: boolean; - /** - * Show circle markers on each point. - * - * @defaultValue `false` - */ - pointMarkersVisible: boolean; - /** - * Circle markers radius in pixels. - * - * @defaultValue `undefined` - */ - pointMarkersRadius?: number; - /** - * Show the crosshair marker. - * - * @defaultValue `true` - */ - crosshairMarkerVisible: boolean; - /** - * Crosshair marker radius in pixels. - * - * @defaultValue `4` - */ - crosshairMarkerRadius: number; - /** - * Crosshair marker border color. An empty string falls back to the color of the series under the crosshair. - * - * @defaultValue `''` - */ - crosshairMarkerBorderColor: string; - /** - * The crosshair marker background color. An empty string falls back to the color of the series under the crosshair. - * - * @defaultValue `''` - */ - crosshairMarkerBackgroundColor: string; - /** - * Crosshair marker border width in pixels. - * - * @defaultValue `2` - */ - crosshairMarkerBorderWidth: number; - /** - * Last price animation mode. - * - * @defaultValue {@link LastPriceAnimationMode.Disabled} - */ - lastPriceAnimation: LastPriceAnimationMode; + /** + * Base value of the series. + * + * @defaultValue `{ type: 'price', price: 0 }` + */ + baseValue: BaseValueType; + /** + * Gradient is relative to the base value and the currently visible range. + * If it is false, the gradient is relative to the top and bottom of the chart. + * + * @defaultValue `false` + */ + relativeGradient: boolean; + /** + * The first color of the top area. + * + * @defaultValue `'rgba(38, 166, 154, 0.28)'` + */ + topFillColor1: string; + /** + * The second color of the top area. + * + * @defaultValue `'rgba(38, 166, 154, 0.05)'` + */ + topFillColor2: string; + /** + * The line color of the top area. + * + * @defaultValue `'rgba(38, 166, 154, 1)'` + */ + topLineColor: string; + /** + * The first color of the bottom area. + * + * @defaultValue `'rgba(239, 83, 80, 0.05)'` + */ + bottomFillColor1: string; + /** + * The second color of the bottom area. + * + * @defaultValue `'rgba(239, 83, 80, 0.28)'` + */ + bottomFillColor2: string; + /** + * The line color of the bottom area. + * + * @defaultValue `'rgba(239, 83, 80, 1)'` + */ + bottomLineColor: string; + /** + * Line width. + * + * @defaultValue `3` + */ + lineWidth: LineWidth; + /** + * Line style. + * + * @defaultValue {@link LineStyle.Solid} + */ + lineStyle: LineStyle; + /** + * Line type. + * + * @defaultValue {@link LineType.Simple} + */ + lineType: LineType; + /** + * Show series line. + * + * @defaultValue `true` + */ + lineVisible: boolean; + /** + * Show circle markers on each point. + * + * @defaultValue `false` + */ + pointMarkersVisible: boolean; + /** + * Circle markers radius in pixels. + * + * @defaultValue `undefined` + */ + pointMarkersRadius?: number; + /** + * Show the crosshair marker. + * + * @defaultValue `true` + */ + crosshairMarkerVisible: boolean; + /** + * Crosshair marker radius in pixels. + * + * @defaultValue `4` + */ + crosshairMarkerRadius: number; + /** + * Crosshair marker border color. An empty string falls back to the color of the series under the crosshair. + * + * @defaultValue `''` + */ + crosshairMarkerBorderColor: string; + /** + * The crosshair marker background color. An empty string falls back to the color of the series under the crosshair. + * + * @defaultValue `''` + */ + crosshairMarkerBackgroundColor: string; + /** + * Crosshair marker border width in pixels. + * + * @defaultValue `2` + */ + crosshairMarkerBorderWidth: number; + /** + * Last price animation mode. + * + * @defaultValue {@link LastPriceAnimationMode.Disabled} + */ + lastPriceAnimation: LastPriceAnimationMode; } /** * Represents a time as a day/month/year. @@ -818,280 +851,284 @@ export interface BaselineStyleOptions { * ``` */ export interface BusinessDay { - /** - * The year. - */ - year: number; - /** - * The month. - */ - month: number; - /** - * The day. - */ - day: number; + /** + * The year. + */ + year: number; + /** + * The month. + */ + month: number; + /** + * The day. + */ + day: number; } /** * Structure describing a single item of data for candlestick series */ -export interface CandlestickData extends OhlcData { - /** - * Optional color value for certain data item. If missed, color from options is used - */ - color?: string; - /** - * Optional border color value for certain data item. If missed, color from options is used - */ - borderColor?: string; - /** - * Optional wick color value for certain data item. If missed, color from options is used - */ - wickColor?: string; +export interface CandlestickData + extends OhlcData { + /** + * Optional color value for certain data item. If missed, color from options is used + */ + color?: string; + /** + * Optional border color value for certain data item. If missed, color from options is used + */ + borderColor?: string; + /** + * Optional wick color value for certain data item. If missed, color from options is used + */ + wickColor?: string; } /** * Represents style options for a candlestick series. */ export interface CandlestickStyleOptions { - /** - * Color of rising candles. - * - * @defaultValue `'#26a69a'` - */ - upColor: string; - /** - * Color of falling candles. - * - * @defaultValue `'#ef5350'` - */ - downColor: string; - /** - * Enable high and low prices candle wicks. - * - * @defaultValue `true` - */ - wickVisible: boolean; - /** - * Enable candle borders. - * - * @defaultValue `true` - */ - borderVisible: boolean; - /** - * Border color. - * - * @defaultValue `'#378658'` - */ - borderColor: string; - /** - * Border color of rising candles. - * - * @defaultValue `'#26a69a'` - */ - borderUpColor: string; - /** - * Border color of falling candles. - * - * @defaultValue `'#ef5350'` - */ - borderDownColor: string; - /** - * Wick color. - * - * @defaultValue `'#737375'` - */ - wickColor: string; - /** - * Wick color of rising candles. - * - * @defaultValue `'#26a69a'` - */ - wickUpColor: string; - /** - * Wick color of falling candles. - * - * @defaultValue `'#ef5350'` - */ - wickDownColor: string; + /** + * Color of rising candles. + * + * @defaultValue `'#26a69a'` + */ + upColor: string; + /** + * Color of falling candles. + * + * @defaultValue `'#ef5350'` + */ + downColor: string; + /** + * Enable high and low prices candle wicks. + * + * @defaultValue `true` + */ + wickVisible: boolean; + /** + * Enable candle borders. + * + * @defaultValue `true` + */ + borderVisible: boolean; + /** + * Border color. + * + * @defaultValue `'#378658'` + */ + borderColor: string; + /** + * Border color of rising candles. + * + * @defaultValue `'#26a69a'` + */ + borderUpColor: string; + /** + * Border color of falling candles. + * + * @defaultValue `'#ef5350'` + */ + borderDownColor: string; + /** + * Wick color. + * + * @defaultValue `'#737375'` + */ + wickColor: string; + /** + * Wick color of rising candles. + * + * @defaultValue `'#26a69a'` + */ + wickUpColor: string; + /** + * Wick color of falling candles. + * + * @defaultValue `'#ef5350'` + */ + wickDownColor: string; } /** * Represents common chart options */ export interface ChartOptionsBase { - /** - * Width of the chart in pixels - * - * @defaultValue If `0` (default) or none value provided, then a size of the widget will be calculated based its container's size. - */ - width: number; - /** - * Height of the chart in pixels - * - * @defaultValue If `0` (default) or none value provided, then a size of the widget will be calculated based its container's size. - */ - height: number; - /** - * Setting this flag to `true` will make the chart watch the chart container's size and automatically resize the chart to fit its container whenever the size changes. - * - * This feature requires [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) class to be available in the global scope. - * Note that calling code is responsible for providing a polyfill if required. If the global scope does not have `ResizeObserver`, a warning will appear and the flag will be ignored. - * - * Please pay attention that `autoSize` option and explicit sizes options `width` and `height` don't conflict with one another. - * If you specify `autoSize` flag, then `width` and `height` options will be ignored unless `ResizeObserver` has failed. If it fails then the values will be used as fallback. - * - * The flag `autoSize` could also be set with and unset with `applyOptions` function. - * ```js - * const chart = LightweightCharts.createChart(document.body, { - * autoSize: true, - * }); - * ``` - */ - autoSize: boolean; - /** - * Layout options - */ - layout: LayoutOptions; - /** - * Left price scale options - */ - leftPriceScale: VisiblePriceScaleOptions; - /** - * Right price scale options - */ - rightPriceScale: VisiblePriceScaleOptions; - /** - * Overlay price scale options - */ - overlayPriceScales: OverlayPriceScaleOptions; - /** - * Time scale options - */ - timeScale: HorzScaleOptions; - /** - * The crosshair shows the intersection of the price and time scale values at any point on the chart. - * - */ - crosshair: CrosshairOptions; - /** - * A grid is represented in the chart background as a vertical and horizontal lines drawn at the levels of visible marks of price and the time scales. - */ - grid: GridOptions; - /** - * Scroll options, or a boolean flag that enables/disables scrolling - */ - handleScroll: HandleScrollOptions | boolean; - /** - * Scale options, or a boolean flag that enables/disables scaling - */ - handleScale: HandleScaleOptions | boolean; - /** - * Kinetic scroll options - */ - kineticScroll: KineticScrollOptions; - /** @inheritDoc TrackingModeOptions - */ - trackingMode: TrackingModeOptions; - /** - * Basic localization options - */ - localization: LocalizationOptionsBase; - /** - * Whether to add a default pane to the chart - * Disable this option when you want to create a chart with no panes and add them manually - * @defaultValue `true` - */ - addDefaultPane: boolean; + /** + * Width of the chart in pixels + * + * @defaultValue If `0` (default) or none value provided, then a size of the widget will be calculated based its container's size. + */ + width: number; + /** + * Height of the chart in pixels + * + * @defaultValue If `0` (default) or none value provided, then a size of the widget will be calculated based its container's size. + */ + height: number; + /** + * Setting this flag to `true` will make the chart watch the chart container's size and automatically resize the chart to fit its container whenever the size changes. + * + * This feature requires [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) class to be available in the global scope. + * Note that calling code is responsible for providing a polyfill if required. If the global scope does not have `ResizeObserver`, a warning will appear and the flag will be ignored. + * + * Please pay attention that `autoSize` option and explicit sizes options `width` and `height` don't conflict with one another. + * If you specify `autoSize` flag, then `width` and `height` options will be ignored unless `ResizeObserver` has failed. If it fails then the values will be used as fallback. + * + * The flag `autoSize` could also be set with and unset with `applyOptions` function. + * ```js + * const chart = LightweightCharts.createChart(document.body, { + * autoSize: true, + * }); + * ``` + */ + autoSize: boolean; + /** + * Layout options + */ + layout: LayoutOptions; + /** + * Left price scale options + */ + leftPriceScale: VisiblePriceScaleOptions; + /** + * Right price scale options + */ + rightPriceScale: VisiblePriceScaleOptions; + /** + * Overlay price scale options + */ + overlayPriceScales: OverlayPriceScaleOptions; + /** + * Time scale options + */ + timeScale: HorzScaleOptions; + /** + * The crosshair shows the intersection of the price and time scale values at any point on the chart. + * + */ + crosshair: CrosshairOptions; + /** + * A grid is represented in the chart background as a vertical and horizontal lines drawn at the levels of visible marks of price and the time scales. + */ + grid: GridOptions; + /** + * Scroll options, or a boolean flag that enables/disables scrolling + */ + handleScroll: HandleScrollOptions | boolean; + /** + * Scale options, or a boolean flag that enables/disables scaling + */ + handleScale: HandleScaleOptions | boolean; + /** + * Kinetic scroll options + */ + kineticScroll: KineticScrollOptions; + /** @inheritDoc TrackingModeOptions + */ + trackingMode: TrackingModeOptions; + /** + * Basic localization options + */ + localization: LocalizationOptionsBase; + /** + * Whether to add a default pane to the chart + * Disable this option when you want to create a chart with no panes and add them manually + * @defaultValue `true` + */ + addDefaultPane: boolean; } /** * Structure describing options of the chart. Series options are to be set separately */ export interface ChartOptionsImpl extends ChartOptionsBase { - /** - * Localization options. - */ - localization: LocalizationOptions; + /** + * Localization options. + */ + localization: LocalizationOptions; } /** Structure describing a crosshair line (vertical or horizontal) */ export interface CrosshairLineOptions { - /** - * Crosshair line color. - * - * @defaultValue `'#758696'` - */ - color: string; - /** - * Crosshair line width. - * - * @defaultValue `1` - */ - width: LineWidth; - /** - * Crosshair line style. - * - * @defaultValue {@link LineStyle.LargeDashed} - */ - style: LineStyle; - /** - * Display the crosshair line. - * - * Note that disabling crosshair lines does not disable crosshair marker on Line and Area series. - * It can be disabled by using `crosshairMarkerVisible` option of a relevant series. - * - * @see {@link LineStyleOptions.crosshairMarkerVisible} - * @see {@link AreaStyleOptions.crosshairMarkerVisible} - * @see {@link BaselineStyleOptions.crosshairMarkerVisible} - * @defaultValue `true` - */ - visible: boolean; - /** - * Display the crosshair label on the relevant scale. - * - * @defaultValue `true` - */ - labelVisible: boolean; - /** - * Crosshair label background color. - * - * @defaultValue `'#4c525e'` - */ - labelBackgroundColor: string; + /** + * Crosshair line color. + * + * @defaultValue `'#758696'` + */ + color: string; + /** + * Crosshair line width. + * + * @defaultValue `1` + */ + width: LineWidth; + /** + * Crosshair line style. + * + * @defaultValue {@link LineStyle.LargeDashed} + */ + style: LineStyle; + /** + * Display the crosshair line. + * + * Note that disabling crosshair lines does not disable crosshair marker on Line and Area series. + * It can be disabled by using `crosshairMarkerVisible` option of a relevant series. + * + * @see {@link LineStyleOptions.crosshairMarkerVisible} + * @see {@link AreaStyleOptions.crosshairMarkerVisible} + * @see {@link BaselineStyleOptions.crosshairMarkerVisible} + * @defaultValue `true` + */ + visible: boolean; + /** + * Display the crosshair label on the relevant scale. + * + * @defaultValue `true` + */ + labelVisible: boolean; + /** + * Crosshair label background color. + * + * @defaultValue `'#4c525e'` + */ + labelBackgroundColor: string; } /** Structure describing crosshair options */ export interface CrosshairOptions { - /** - * Crosshair mode - * - * @defaultValue {@link CrosshairMode.Magnet} - */ - mode: CrosshairMode; - /** - * Vertical line options. - */ - vertLine: CrosshairLineOptions; - /** - * Horizontal line options. - */ - horzLine: CrosshairLineOptions; + /** + * Crosshair mode + * + * @defaultValue {@link CrosshairMode.Magnet} + */ + mode: CrosshairMode; + /** + * Vertical line options. + */ + vertLine: CrosshairLineOptions; + /** + * Horizontal line options. + */ + horzLine: CrosshairLineOptions; } /** * Renderer data for an item within the custom series. */ -export interface CustomBarItemData = CustomData> { - /** - * Horizontal coordinate for the item. Measured from the left edge of the pane in pixels. - */ - x: number; - /** - * Time scale index for the item. This isn't the timestamp but rather the logical index. - */ - time: number; - /** - * Original data for the item. - */ - originalData: TData; - /** - * Color assigned for the item, typically used for price line and price scale label. - */ - barColor: string; +export interface CustomBarItemData< + HorzScaleItem, + TData extends CustomData = CustomData, +> { + /** + * Horizontal coordinate for the item. Measured from the left edge of the pane in pixels. + */ + x: number; + /** + * Time scale index for the item. This isn't the timestamp but rather the logical index. + */ + time: number; + /** + * Original data for the item. + */ + originalData: TData; + /** + * Color assigned for the item, typically used for price line and price scale label. + */ + barColor: string; } /** * Base structure describing a single item of data for a custom series. @@ -1100,1515 +1137,1602 @@ export interface CustomBarItemData extends CustomSeriesWhitespaceData { - /** - * If defined then this color will be used for the price line and price scale line - * for this specific data item of the custom series. - */ - color?: string; +export interface CustomData + extends CustomSeriesWhitespaceData { + /** + * If defined then this color will be used for the price line and price scale line + * for this specific data item of the custom series. + */ + color?: string; } /** * Represents a whitespace data item, which is a data point without a value. */ export interface CustomSeriesWhitespaceData { - /** - * The time of the data. - */ - time: HorzScaleItem; - /** - * Additional custom values which will be ignored by the library, but - * could be used by plugins. - */ - customValues?: Record; + /** + * The time of the data. + */ + time: HorzScaleItem; + /** + * Additional custom values which will be ignored by the library, but + * could be used by plugins. + */ + customValues?: Record; } /** * Represents style options for a custom series. */ export interface CustomStyleOptions { - /** - * Color used for the price line and price scale label. - */ - color: string; + /** + * Color used for the price line and price scale label. + */ + color: string; } /** * Helper drawing utilities exposed by the library to a Primitive (a.k.a plugin). */ export interface DrawingUtils { - /** - * Drawing utility to change the line style on the canvas context to one of the - * built-in line styles. - * @param ctx - 2D rendering context for the target canvas. - * @param lineStyle - Built-in {@link LineStyle} to set on the canvas context. - */ - readonly setLineStyle: (ctx: CanvasRenderingContext2D, lineStyle: LineStyle) => void; + /** + * Drawing utility to change the line style on the canvas context to one of the + * built-in line styles. + * @param ctx - 2D rendering context for the target canvas. + * @param lineStyle - Built-in {@link LineStyle} to set on the canvas context. + */ + readonly setLineStyle: ( + ctx: CanvasRenderingContext2D, + lineStyle: LineStyle, + ) => void; } /** Grid line options. */ export interface GridLineOptions { - /** - * Line color. - * - * @defaultValue `'#D6DCDE'` - */ - color: string; - /** - * Line style. - * - * @defaultValue {@link LineStyle.Solid} - */ - style: LineStyle; - /** - * Display the lines. - * - * @defaultValue `true` - */ - visible: boolean; + /** + * Line color. + * + * @defaultValue `'#D6DCDE'` + */ + color: string; + /** + * Line style. + * + * @defaultValue {@link LineStyle.Solid} + */ + style: LineStyle; + /** + * Display the lines. + * + * @defaultValue `true` + */ + visible: boolean; } /** Structure describing grid options. */ export interface GridOptions { - /** - * Vertical grid line options. - */ - vertLines: GridLineOptions; - /** - * Horizontal grid line options. - */ - horzLines: GridLineOptions; + /** + * Vertical grid line options. + */ + vertLines: GridLineOptions; + /** + * Horizontal grid line options. + */ + horzLines: GridLineOptions; } /** * Represents options for how the chart is scaled by the mouse and touch gestures. */ export interface HandleScaleOptions { - /** - * Enable scaling with the mouse wheel. - * - * @defaultValue `true` - */ - mouseWheel: boolean; - /** - * Enable scaling with pinch/zoom gestures. - * - * @defaultValue `true` - */ - pinch: boolean; - /** - * Enable scaling the price and/or time scales by holding down the left mouse button and moving the mouse. - */ - axisPressedMouseMove: AxisPressedMouseMoveOptions | boolean; - /** - * Enable resetting scaling by double-clicking the left mouse button. - */ - axisDoubleClickReset: AxisDoubleClickOptions | boolean; + /** + * Enable scaling with the mouse wheel. + * + * @defaultValue `true` + */ + mouseWheel: boolean; + /** + * Enable scaling with pinch/zoom gestures. + * + * @defaultValue `true` + */ + pinch: boolean; + /** + * Enable scaling the price and/or time scales by holding down the left mouse button and moving the mouse. + */ + axisPressedMouseMove: AxisPressedMouseMoveOptions | boolean; + /** + * Enable resetting scaling by double-clicking the left mouse button. + */ + axisDoubleClickReset: AxisDoubleClickOptions | boolean; } /** * Represents options for how the chart is scrolled by the mouse and touch gestures. */ export interface HandleScrollOptions { - /** - * Enable scrolling with the mouse wheel. - * - * @defaultValue `true` - */ - mouseWheel: boolean; - /** - * Enable scrolling by holding down the left mouse button and moving the mouse. - * - * @defaultValue `true` - */ - pressedMouseMove: boolean; - /** - * Enable horizontal touch scrolling. - * - * When enabled the chart handles touch gestures that would normally scroll the webpage horizontally. - * - * @defaultValue `true` - */ - horzTouchDrag: boolean; - /** - * Enable vertical touch scrolling. - * - * When enabled the chart handles touch gestures that would normally scroll the webpage vertically. - * - * @defaultValue `true` - */ - vertTouchDrag: boolean; + /** + * Enable scrolling with the mouse wheel. + * + * @defaultValue `true` + */ + mouseWheel: boolean; + /** + * Enable scrolling by holding down the left mouse button and moving the mouse. + * + * @defaultValue `true` + */ + pressedMouseMove: boolean; + /** + * Enable horizontal touch scrolling. + * + * When enabled the chart handles touch gestures that would normally scroll the webpage horizontally. + * + * @defaultValue `true` + */ + horzTouchDrag: boolean; + /** + * Enable vertical touch scrolling. + * + * When enabled the chart handles touch gestures that would normally scroll the webpage vertically. + * + * @defaultValue `true` + */ + vertTouchDrag: boolean; } /** * Structure describing a single item of data for histogram series */ -export interface HistogramData extends SingleValueData { - /** - * Optional color value for certain data item. If missed, color from options is used - */ - color?: string; +export interface HistogramData + extends SingleValueData { + /** + * Optional color value for certain data item. If missed, color from options is used + */ + color?: string; } /** * Represents style options for a histogram series. */ export interface HistogramStyleOptions { - /** - * Column color. - * - * @defaultValue `'#26a69a'` - */ - color: string; - /** - * Initial level of histogram columns. - * - * @defaultValue `0` - */ - base: number; + /** + * Column color. + * + * @defaultValue `'#26a69a'` + */ + color: string; + /** + * Initial level of histogram columns. + * + * @defaultValue `0` + */ + base: number; } /** * Options for the time scale; the horizontal scale at the bottom of the chart that displays the time of data. */ export interface HorzScaleOptions { - /** - * The margin space in bars from the right side of the chart. - * - * @defaultValue `0` - */ - rightOffset: number; - /** - * The margin space in pixels from the right side of the chart. - * This option has priority over `rightOffset`. - * - * @defaultValue `undefined` - */ - rightOffsetPixels?: number; - /** - * The space between bars in pixels. - * - * @defaultValue `6` - */ - barSpacing: number; - /** - * The minimum space between bars in pixels. - * - * @defaultValue `0.5` - */ - minBarSpacing: number; - /** - * The maximum space between bars in pixels. - * - * Has no effect if value is set to `0`. - * - * @defaultValue `0` - */ - maxBarSpacing: number; - /** - * Prevent scrolling to the left of the first bar. - * - * @defaultValue `false` - */ - fixLeftEdge: boolean; - /** - * Prevent scrolling to the right of the most recent bar. - * - * @defaultValue `false` - */ - fixRightEdge: boolean; - /** - * Prevent changing the visible time range during chart resizing. - * - * @defaultValue `false` - */ - lockVisibleTimeRangeOnResize: boolean; - /** - * Prevent the hovered bar from moving when scrolling. - * - * @defaultValue `false` - */ - rightBarStaysOnScroll: boolean; - /** - * Show the time scale border. - * - * @defaultValue `true` - */ - borderVisible: boolean; - /** - * The time scale border color. - * - * @defaultValue `'#2B2B43'` - */ - borderColor: string; - /** - * Show the time scale. - * - * @defaultValue `true` - */ - visible: boolean; - /** - * Show the time, not just the date, in the time scale and vertical crosshair label. - * - * @defaultValue `false` - */ - timeVisible: boolean; - /** - * Show seconds in the time scale and vertical crosshair label in `hh:mm:ss` format for intraday data. - * - * @defaultValue `true` - */ - secondsVisible: boolean; - /** - * Shift the visible range to the right (into the future) by the number of new bars when new data is added. - * - * Note that this only applies when the last bar is visible. - * - * @defaultValue `true` - */ - shiftVisibleRangeOnNewBar: boolean; - /** - * Allow the visible range to be shifted to the right when a new bar is added which - * is replacing an existing whitespace time point on the chart. - * - * Note that this only applies when the last bar is visible & `shiftVisibleRangeOnNewBar` is enabled. - * - * @defaultValue `false` - */ - allowShiftVisibleRangeOnWhitespaceReplacement: boolean; - /** - * Draw small vertical line on time axis labels. - * - * @defaultValue `false` - */ - ticksVisible: boolean; - /** - * Maximum tick mark label length. Used to override the default 8 character maximum length. - * - * @defaultValue `undefined` - */ - tickMarkMaxCharacterLength?: number; - /** - * Changes horizontal scale marks generation. - * With this flag equal to `true`, marks of the same weight are either all drawn or none are drawn at all. - */ - uniformDistribution: boolean; - /** - * Define a minimum height for the time scale. - * Note: This value will be exceeded if the - * time scale needs more space to display it's contents. - * - * Setting a minimum height could be useful for ensuring that - * multiple charts positioned in a horizontal stack each have - * an identical time scale height, or for plugins which - * require a bit more space within the time scale pane. - * - * @defaultValue 0 - */ - minimumHeight: number; - /** - * Allow major time scale labels to be rendered in a bolder font weight. - * - * @defaultValue true - */ - allowBoldLabels: boolean; - /** - * Ignore time scale points containing only whitespace (for all series) when - * drawing grid lines, tick marks, and snapping the crosshair to time scale points. - * - * For the yield curve chart type it defaults to `true`. - * - * @defaultValue false - */ - ignoreWhitespaceIndices: boolean; + /** + * The margin space in bars from the right side of the chart. + * + * @defaultValue `0` + */ + rightOffset: number; + /** + * The margin space in pixels from the right side of the chart. + * This option has priority over `rightOffset`. + * + * @defaultValue `undefined` + */ + rightOffsetPixels?: number; + /** + * The space between bars in pixels. + * + * @defaultValue `6` + */ + barSpacing: number; + /** + * The minimum space between bars in pixels. + * + * @defaultValue `0.5` + */ + minBarSpacing: number; + /** + * The maximum space between bars in pixels. + * + * Has no effect if value is set to `0`. + * + * @defaultValue `0` + */ + maxBarSpacing: number; + /** + * Prevent scrolling to the left of the first bar. + * + * @defaultValue `false` + */ + fixLeftEdge: boolean; + /** + * Prevent scrolling to the right of the most recent bar. + * + * @defaultValue `false` + */ + fixRightEdge: boolean; + /** + * Prevent changing the visible time range during chart resizing. + * + * @defaultValue `false` + */ + lockVisibleTimeRangeOnResize: boolean; + /** + * Prevent the hovered bar from moving when scrolling. + * + * @defaultValue `false` + */ + rightBarStaysOnScroll: boolean; + /** + * Show the time scale border. + * + * @defaultValue `true` + */ + borderVisible: boolean; + /** + * The time scale border color. + * + * @defaultValue `'#2B2B43'` + */ + borderColor: string; + /** + * Show the time scale. + * + * @defaultValue `true` + */ + visible: boolean; + /** + * Show the time, not just the date, in the time scale and vertical crosshair label. + * + * @defaultValue `false` + */ + timeVisible: boolean; + /** + * Show seconds in the time scale and vertical crosshair label in `hh:mm:ss` format for intraday data. + * + * @defaultValue `true` + */ + secondsVisible: boolean; + /** + * Shift the visible range to the right (into the future) by the number of new bars when new data is added. + * + * Note that this only applies when the last bar is visible. + * + * @defaultValue `true` + */ + shiftVisibleRangeOnNewBar: boolean; + /** + * Allow the visible range to be shifted to the right when a new bar is added which + * is replacing an existing whitespace time point on the chart. + * + * Note that this only applies when the last bar is visible & `shiftVisibleRangeOnNewBar` is enabled. + * + * @defaultValue `false` + */ + allowShiftVisibleRangeOnWhitespaceReplacement: boolean; + /** + * Draw small vertical line on time axis labels. + * + * @defaultValue `false` + */ + ticksVisible: boolean; + /** + * Maximum tick mark label length. Used to override the default 8 character maximum length. + * + * @defaultValue `undefined` + */ + tickMarkMaxCharacterLength?: number; + /** + * Changes horizontal scale marks generation. + * With this flag equal to `true`, marks of the same weight are either all drawn or none are drawn at all. + */ + uniformDistribution: boolean; + /** + * Define a minimum height for the time scale. + * Note: This value will be exceeded if the + * time scale needs more space to display it's contents. + * + * Setting a minimum height could be useful for ensuring that + * multiple charts positioned in a horizontal stack each have + * an identical time scale height, or for plugins which + * require a bit more space within the time scale pane. + * + * @defaultValue 0 + */ + minimumHeight: number; + /** + * Allow major time scale labels to be rendered in a bolder font weight. + * + * @defaultValue true + */ + allowBoldLabels: boolean; + /** + * Ignore time scale points containing only whitespace (for all series) when + * drawing grid lines, tick marks, and snapping the crosshair to time scale points. + * + * For the yield curve chart type it defaults to `true`. + * + * @defaultValue false + */ + ignoreWhitespaceIndices: boolean; } /** * The main interface of a single chart using time for horizontal scale. */ export interface IChartApi extends IChartApiBase