global: add some market charts

This commit is contained in:
nym21
2025-05-09 16:04:54 +02:00
parent 851a6aac0e
commit 9f20664c6e
17 changed files with 449 additions and 46 deletions

View File

@@ -8,7 +8,7 @@ use brk_vec::{
};
use crate::storage::{
marketprice,
fetched,
vecs::{Indexes, indexes},
};
@@ -68,7 +68,7 @@ impl ComputedValueVecsFromHeight {
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
marketprices: Option<&marketprice::Vecs>,
fetched: Option<&fetched::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
@@ -91,14 +91,7 @@ impl ComputedValueVecsFromHeight {
)?;
let height: Option<&StoredVec<Height, Sats>> = None;
self.compute_rest(
indexer,
indexes,
marketprices,
starting_indexes,
exit,
height,
)?;
self.compute_rest(indexer, indexes, fetched, starting_indexes, exit, height)?;
Ok(())
}
@@ -107,7 +100,7 @@ impl ComputedValueVecsFromHeight {
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
marketprices: Option<&marketprice::Vecs>,
fetched: Option<&fetched::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
height: Option<&impl CollectableVec<Height, Sats>>,
@@ -147,7 +140,7 @@ impl ComputedValueVecsFromHeight {
}
let txindex = self.bitcoin.height.as_ref().unwrap();
let price = &marketprices.as_ref().unwrap().chainindexes_to_close.height;
let price = &fetched.as_ref().unwrap().chainindexes_to_close.height;
if let Some(dollars) = self.dollars.as_mut() {
dollars.compute_all(

View File

@@ -9,7 +9,7 @@ use brk_vec::{
};
use crate::storage::{
marketprice,
fetched,
vecs::{Indexes, indexes},
};
@@ -48,11 +48,11 @@ impl ComputedValueVecsFromTxindex {
version: Version,
computation: Computation,
compressed: Compressed,
marketprices: Option<&marketprice::Vecs>,
fetched: Option<&fetched::Vecs>,
options: StorableVecGeneatorOptions,
) -> color_eyre::Result<Self> {
let compute_source = source.is_none();
let compute_dollars = marketprices.is_some();
let compute_dollars = fetched.is_some();
let sats = ComputedVecsFromTxindex::forced_import(
path,
@@ -84,7 +84,7 @@ impl ComputedValueVecsFromTxindex {
options,
)?;
let dollars_txindex = marketprices.map(|marketprices| {
let dollars_txindex = fetched.map(|fetched| {
ComputedVecFrom3::forced_import_or_init_from_3(
computation,
path,
@@ -93,7 +93,7 @@ impl ComputedValueVecsFromTxindex {
compressed,
bitcoin_txindex.boxed_clone(),
indexes.txindex_to_height.boxed_clone(),
marketprices.chainindexes_to_close.height.boxed_clone(),
fetched.chainindexes_to_close.height.boxed_clone(),
|txindex: TxIndex,
txindex_to_btc_iter,
txindex_to_height_iter,
@@ -138,7 +138,7 @@ impl ComputedValueVecsFromTxindex {
// &mut self,
// indexer: &Indexer,
// indexes: &indexes::Vecs,
// marketprices: Option<&marketprice::Vecs>,
// fetched: Option<&marketprice::Vecs>,
// starting_indexes: &Indexes,
// exit: &Exit,
// mut compute: F,
@@ -164,7 +164,7 @@ impl ComputedValueVecsFromTxindex {
// self.compute_rest(
// indexer,
// indexes,
// marketprices,
// fetched,
// starting_indexes,
// exit,
// txindex,

View File

@@ -0,0 +1,253 @@
use std::{fs, path::Path};
use brk_core::{Dollars, StoredF64, StoredUsize};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, Compressed, Computation, StoredIndex, VecIterator, Version};
use super::{
Indexes, fetched,
grouped::{ComputedVecsFromDateindex, StorableVecGeneatorOptions},
indexes, transactions,
};
#[derive(Clone)]
pub struct Vecs {
pub indexes_to_marketcap: ComputedVecsFromDateindex<Dollars>,
pub indexes_to_ath: ComputedVecsFromDateindex<Dollars>,
pub indexes_to_drawdown: ComputedVecsFromDateindex<StoredF64>,
pub indexes_to_days_since_ath: ComputedVecsFromDateindex<StoredUsize>,
pub indexes_to_max_days_between_ath: ComputedVecsFromDateindex<StoredUsize>,
pub indexes_to_max_years_between_ath: ComputedVecsFromDateindex<StoredF64>,
}
impl Vecs {
pub fn forced_import(
path: &Path,
_computation: Computation,
compressed: Compressed,
) -> color_eyre::Result<Self> {
fs::create_dir_all(path)?;
Ok(Self {
indexes_to_marketcap: ComputedVecsFromDateindex::forced_import(
path,
"marketcap",
Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_last(),
)?,
indexes_to_ath: ComputedVecsFromDateindex::forced_import(
path,
"ath",
Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_last(),
)?,
indexes_to_drawdown: ComputedVecsFromDateindex::forced_import(
path,
"drawdown",
Version::ONE,
compressed,
StorableVecGeneatorOptions::default().add_last(),
)?,
indexes_to_days_since_ath: ComputedVecsFromDateindex::forced_import(
path,
"days_since_ath",
Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_last(),
)?,
indexes_to_max_days_between_ath: ComputedVecsFromDateindex::forced_import(
path,
"max_days_between_ath",
Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_last(),
)?,
indexes_to_max_years_between_ath: ComputedVecsFromDateindex::forced_import(
path,
"max_years_between_ath",
Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_last(),
)?,
})
}
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
fetched: &fetched::Vecs,
transactions: &mut transactions::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> color_eyre::Result<()> {
self.indexes_to_marketcap.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
let mut total_subsidy_in_btc = transactions
.indexes_to_subsidy
.bitcoin
.dateindex
.unwrap_total()
.into_iter();
v.compute_transform(
starting_indexes.dateindex,
&fetched.timeindexes_to_close.dateindex,
|(i, close, ..)| {
let supply = total_subsidy_in_btc.unwrap_get_inner(i);
(i, *close * supply)
},
exit,
)
},
)?;
self.indexes_to_ath.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
let mut prev = None;
v.compute_transform(
starting_indexes.dateindex,
&fetched.timeindexes_to_high.dateindex,
|(i, high, slf)| {
if prev.is_none() {
let i = i.unwrap_to_usize();
prev.replace(if i > 0 {
slf.into_iter().unwrap_get_inner_(i - 1)
} else {
Dollars::ZERO
});
}
let ath = prev.unwrap().max(*high);
prev.replace(ath);
(i, ath)
},
exit,
)
},
)?;
self.indexes_to_drawdown.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
let mut close_iter = fetched.timeindexes_to_close.dateindex.into_iter();
v.compute_transform(
starting_indexes.dateindex,
&self.indexes_to_ath.dateindex,
|(i, ath, ..)| {
if ath == Dollars::ZERO {
return (i, StoredF64::default());
}
let close = *close_iter.unwrap_get_inner(i);
let drawdown = StoredF64::from((*ath - *close) / *ath * -100.0);
(i, drawdown)
},
exit,
)
},
)?;
self.indexes_to_days_since_ath.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
let mut high_iter = fetched.timeindexes_to_high.dateindex.into_iter();
let mut prev = None;
v.compute_transform(
starting_indexes.dateindex,
&self.indexes_to_ath.dateindex,
|(i, ath, slf)| {
if prev.is_none() {
let i = i.unwrap_to_usize();
prev.replace(if i > 0 {
slf.into_iter().unwrap_get_inner_(i - 1)
} else {
StoredUsize::default()
});
}
let days = if *high_iter.unwrap_get_inner(i) == ath {
StoredUsize::default()
} else {
prev.unwrap() + StoredUsize::from(1)
};
prev.replace(days);
(i, days)
},
exit,
)
},
)?;
self.indexes_to_max_days_between_ath.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
let mut prev = None;
v.compute_transform(
starting_indexes.dateindex,
&self.indexes_to_days_since_ath.dateindex,
|(i, days, slf)| {
if prev.is_none() {
let i = i.unwrap_to_usize();
prev.replace(if i > 0 {
slf.into_iter().unwrap_get_inner_(i - 1)
} else {
StoredUsize::ZERO
});
}
let max = prev.unwrap().max(days);
prev.replace(max);
(i, max)
},
exit,
)
},
)?;
self.indexes_to_max_years_between_ath.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform(
starting_indexes.dateindex,
&self.indexes_to_max_days_between_ath.dateindex,
|(i, max, ..)| (i, StoredF64::from(*max as f64 / 365.0)),
exit,
)
},
)?;
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.indexes_to_marketcap.vecs(),
self.indexes_to_ath.vecs(),
self.indexes_to_drawdown.vecs(),
self.indexes_to_days_since_ath.vecs(),
self.indexes_to_max_days_between_ath.vecs(),
self.indexes_to_max_years_between_ath.vecs(),
]
.concat()
}
}

View File

@@ -6,9 +6,10 @@ use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, Compressed, Computation};
pub mod blocks;
pub mod fetched;
pub mod grouped;
pub mod indexes;
pub mod marketprice;
pub mod market;
pub mod mining;
pub mod transactions;
@@ -19,8 +20,9 @@ pub struct Vecs {
pub indexes: indexes::Vecs,
pub blocks: blocks::Vecs,
pub mining: mining::Vecs,
pub market: market::Vecs,
pub transactions: transactions::Vecs,
pub marketprice: Option<marketprice::Vecs>,
pub fetched: Option<fetched::Vecs>,
}
impl Vecs {
@@ -35,22 +37,23 @@ impl Vecs {
let indexes = indexes::Vecs::forced_import(path, indexer, computation, compressed)?;
let marketprice =
fetch.then(|| marketprice::Vecs::forced_import(path, computation, compressed).unwrap());
let fetched =
fetch.then(|| fetched::Vecs::forced_import(path, computation, compressed).unwrap());
Ok(Self {
blocks: blocks::Vecs::forced_import(path, computation, compressed)?,
mining: mining::Vecs::forced_import(path, computation, compressed)?,
market: market::Vecs::forced_import(path, computation, compressed)?,
transactions: transactions::Vecs::forced_import(
path,
indexer,
&indexes,
computation,
compressed,
marketprice.as_ref(),
fetched.as_ref(),
)?,
indexes,
marketprice,
fetched,
})
}
@@ -69,8 +72,8 @@ impl Vecs {
self.mining
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
if let Some(marketprice) = self.marketprice.as_mut() {
marketprice.compute(
if let Some(fetched) = self.fetched.as_mut() {
fetched.compute(
indexer,
&self.indexes,
&starting_indexes,
@@ -83,10 +86,21 @@ impl Vecs {
indexer,
&self.indexes,
&starting_indexes,
self.marketprice.as_ref(),
self.fetched.as_ref(),
exit,
)?;
if let Some(fetched) = self.fetched.as_ref() {
self.market.compute(
indexer,
&self.indexes,
fetched,
&mut self.transactions,
&starting_indexes,
exit,
)?;
}
Ok(())
}
@@ -95,8 +109,9 @@ impl Vecs {
self.indexes.vecs(),
self.blocks.vecs(),
self.mining.vecs(),
self.market.vecs(),
self.transactions.vecs(),
self.marketprice.as_ref().map_or(vec![], |v| v.vecs()),
self.fetched.as_ref().map_or(vec![], |v| v.vecs()),
]
.concat()
}

View File

@@ -13,12 +13,12 @@ use brk_vec::{
};
use super::{
Indexes,
Indexes, fetched,
grouped::{
ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromHeight,
ComputedVecsFromTxindex, StorableVecGeneatorOptions,
},
indexes, marketprice,
indexes,
};
#[derive(Clone)]
@@ -94,9 +94,9 @@ impl Vecs {
indexes: &indexes::Vecs,
computation: Computation,
compressed: Compressed,
marketprices: Option<&marketprice::Vecs>,
fetched: Option<&fetched::Vecs>,
) -> color_eyre::Result<Self> {
let compute_dollars = marketprices.is_some();
let compute_dollars = fetched.is_some();
fs::create_dir_all(path)?;
@@ -455,7 +455,7 @@ impl Vecs {
Version::ZERO,
computation,
compressed,
marketprices,
fetched,
StorableVecGeneatorOptions::default()
.add_sum()
.add_total()
@@ -700,7 +700,7 @@ impl Vecs {
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
marketprices: Option<&marketprice::Vecs>,
fetched: Option<&fetched::Vecs>,
exit: &Exit,
) -> color_eyre::Result<()> {
self.indexes_to_tx_count.compute_all(
@@ -845,7 +845,7 @@ impl Vecs {
self.indexes_to_coinbase.compute_all(
indexer,
indexes,
marketprices,
fetched,
starting_indexes,
exit,
|vec, indexer, _, starting_indexes, exit| {
@@ -878,7 +878,7 @@ impl Vecs {
self.indexes_to_subsidy.compute_all(
indexer,
indexes,
marketprices,
fetched,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {