mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: wip
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -35,3 +35,6 @@ _outputs
|
||||
|
||||
# Logs
|
||||
.log
|
||||
|
||||
# Cloudflare
|
||||
cloudflared
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use std::path::Path;
|
||||
|
||||
use brk_core::{Bitcoin, DateIndex, Dollars, Sats, Version};
|
||||
use brk_core::{Bitcoin, DateIndex, Dollars, Result, Sats, Version};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyCollectableVec, CollectableVec, Format, StoredVec};
|
||||
use brk_vec::{AnyCollectableVec, CollectableVec, EagerVec, Format, StoredVec};
|
||||
|
||||
use crate::vecs::{Indexes, fetched, grouped::ComputedVecsFromDateIndex, indexes};
|
||||
|
||||
@@ -59,37 +59,37 @@ impl ComputedValueVecsFromDateIndex {
|
||||
})
|
||||
}
|
||||
|
||||
// pub fn compute_all<F>(
|
||||
// &mut self,
|
||||
// indexer: &Indexer,
|
||||
// indexes: &indexes::Vecs,
|
||||
// fetched: Option<&fetched::Vecs>,
|
||||
// starting_indexes: &Indexes,
|
||||
// exit: &Exit,
|
||||
// mut compute: F,
|
||||
// ) -> color_eyre::Result<()>
|
||||
// where
|
||||
// F: FnMut(
|
||||
// &mut EagerVec<DateIndex, Sats>,
|
||||
// &Indexer,
|
||||
// &indexes::Vecs,
|
||||
// &Indexes,
|
||||
// &Exit,
|
||||
// ) -> Result<()>,
|
||||
// {
|
||||
// compute(
|
||||
// self.sats.dateindex.as_mut().unwrap(),
|
||||
// indexer,
|
||||
// indexes,
|
||||
// starting_indexes,
|
||||
// exit,
|
||||
// )?;
|
||||
pub fn compute_all<F>(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
fetched: Option<&fetched::Vecs>,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
mut compute: F,
|
||||
) -> color_eyre::Result<()>
|
||||
where
|
||||
F: FnMut(
|
||||
&mut EagerVec<DateIndex, Sats>,
|
||||
&Indexer,
|
||||
&indexes::Vecs,
|
||||
&Indexes,
|
||||
&Exit,
|
||||
) -> Result<()>,
|
||||
{
|
||||
compute(
|
||||
self.sats.dateindex.as_mut().unwrap(),
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// let dateindex: Option<&StoredVec<DateIndex, Sats>> = None;
|
||||
// self.compute_rest(indexer, indexes, fetched, starting_indexes, exit, dateindex)?;
|
||||
let dateindex: Option<&StoredVec<DateIndex, Sats>> = None;
|
||||
self.compute_rest(indexer, indexes, fetched, starting_indexes, exit, dateindex)?;
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compute_rest(
|
||||
&mut self,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use std::path::Path;
|
||||
|
||||
use brk_core::{Bitcoin, Dollars, Height, Sats, Version};
|
||||
use brk_core::{Bitcoin, Dollars, Height, Result, Sats, Version};
|
||||
use brk_exit::Exit;
|
||||
use brk_vec::{AnyCollectableVec, CollectableVec, EagerVec, Format};
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyCollectableVec, CollectableVec, EagerVec, Format, StoredVec};
|
||||
|
||||
use crate::vecs::{Indexes, fetched};
|
||||
use crate::vecs::{Indexes, fetched, indexes};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedHeightValueVecs {
|
||||
@@ -47,37 +48,37 @@ impl ComputedHeightValueVecs {
|
||||
})
|
||||
}
|
||||
|
||||
// pub fn compute_all<F>(
|
||||
// &mut self,
|
||||
// indexer: &Indexer,
|
||||
// indexes: &indexes::Vecs,
|
||||
// fetched: Option<&fetched::Vecs>,
|
||||
// starting_indexes: &Indexes,
|
||||
// exit: &Exit,
|
||||
// mut compute: F,
|
||||
// ) -> color_eyre::Result<()>
|
||||
// where
|
||||
// F: FnMut(
|
||||
// &mut EagerVec<Height, Sats>,
|
||||
// &Indexer,
|
||||
// &indexes::Vecs,
|
||||
// &Indexes,
|
||||
// &Exit,
|
||||
// ) -> Result<()>,
|
||||
// {
|
||||
// compute(
|
||||
// self.sats.as_mut().unwrap(),
|
||||
// indexer,
|
||||
// indexes,
|
||||
// starting_indexes,
|
||||
// exit,
|
||||
// )?;
|
||||
pub fn compute_all<F>(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
fetched: Option<&fetched::Vecs>,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
mut compute: F,
|
||||
) -> color_eyre::Result<()>
|
||||
where
|
||||
F: FnMut(
|
||||
&mut EagerVec<Height, Sats>,
|
||||
&Indexer,
|
||||
&indexes::Vecs,
|
||||
&Indexes,
|
||||
&Exit,
|
||||
) -> Result<()>,
|
||||
{
|
||||
compute(
|
||||
self.sats.as_mut().unwrap(),
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// let height: Option<&StoredVec<Height, Sats>> = None;
|
||||
// self.compute_rest(fetched, starting_indexes, exit, height)?;
|
||||
let height: Option<&StoredVec<Height, Sats>> = None;
|
||||
self.compute_rest(fetched, starting_indexes, exit, height)?;
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compute_rest(
|
||||
&mut self,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use core::panic;
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use brk_core::{
|
||||
DateIndex, Dollars, Height, Result, Sats, StoredF32, StoredF64, StoredUsize, Version,
|
||||
Bitcoin, DateIndex, Dollars, Height, Result, Sats, StoredF32, StoredF64, StoredUsize, Version,
|
||||
};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
@@ -16,8 +17,7 @@ use crate::vecs::{
|
||||
Indexes, fetched,
|
||||
grouped::{
|
||||
ComputedHeightValueVecs, ComputedRatioVecsFromDateIndex, ComputedValueVecsFromDateIndex,
|
||||
ComputedValueVecsFromHeight, ComputedVecsFromDateIndex, ComputedVecsFromHeight,
|
||||
StorableVecGeneatorOptions,
|
||||
ComputedVecsFromDateIndex, ComputedVecsFromHeight, StorableVecGeneatorOptions,
|
||||
},
|
||||
indexes, market,
|
||||
};
|
||||
@@ -52,7 +52,11 @@ pub struct Vecs {
|
||||
pub height_to_unrealized_profit: Option<EagerVec<Height, Dollars>>,
|
||||
pub height_to_value_created: Option<EagerVec<Height, Dollars>>,
|
||||
pub height_to_value_destroyed: Option<EagerVec<Height, Dollars>>,
|
||||
pub height_to_satblocks_destroyed: EagerVec<Height, Sats>,
|
||||
pub height_to_satdays_destroyed: EagerVec<Height, Sats>,
|
||||
|
||||
pub indexes_to_coinblocks_destroyed: ComputedVecsFromHeight<Bitcoin>,
|
||||
pub indexes_to_coindays_destroyed: ComputedVecsFromHeight<Bitcoin>,
|
||||
pub dateindex_to_adjusted_spent_output_profit_ratio: Option<EagerVec<DateIndex, StoredF32>>,
|
||||
pub dateindex_to_realized_cap_30d_change: Option<EagerVec<DateIndex, Dollars>>,
|
||||
pub dateindex_to_sell_side_risk_ratio: Option<EagerVec<DateIndex, StoredF32>>,
|
||||
@@ -67,7 +71,8 @@ pub struct Vecs {
|
||||
pub indexes_to_realized_price_extra: Option<ComputedRatioVecsFromDateIndex>,
|
||||
pub indexes_to_realized_profit: Option<ComputedVecsFromHeight<Dollars>>,
|
||||
pub indexes_to_realized_value: Option<ComputedVecsFromHeight<Dollars>>,
|
||||
pub indexes_to_supply: ComputedValueVecsFromHeight,
|
||||
pub height_to_supply_value: ComputedHeightValueVecs,
|
||||
pub indexes_to_supply: ComputedValueVecsFromDateIndex,
|
||||
pub indexes_to_utxo_count: ComputedVecsFromHeight<StoredUsize>,
|
||||
pub indexes_to_value_created: Option<ComputedVecsFromHeight<Dollars>>,
|
||||
pub indexes_to_value_destroyed: Option<ComputedVecsFromHeight<Dollars>>,
|
||||
@@ -75,7 +80,8 @@ pub struct Vecs {
|
||||
pub indexes_to_unrealized_loss: Option<ComputedVecsFromDateIndex<Dollars>>,
|
||||
pub indexes_to_min_price_paid: Option<ComputedVecsFromHeight<Dollars>>,
|
||||
pub indexes_to_max_price_paid: Option<ComputedVecsFromHeight<Dollars>>,
|
||||
pub indexes_to_halved_supply: ComputedValueVecsFromHeight,
|
||||
pub height_to_halved_supply_value: ComputedHeightValueVecs,
|
||||
pub indexes_to_halved_supply: ComputedValueVecsFromDateIndex,
|
||||
pub height_to_negative_unrealized_loss: Option<EagerVec<Height, Dollars>>,
|
||||
pub indexes_to_negative_unrealized_loss: Option<ComputedVecsFromDateIndex<Dollars>>,
|
||||
pub height_to_net_unrealized_profit_and_loss: Option<EagerVec<Height, Dollars>>,
|
||||
@@ -139,7 +145,7 @@ impl Vecs {
|
||||
keyspace,
|
||||
stores_path,
|
||||
cohort_name.unwrap_or_default(),
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
compute_dollars,
|
||||
)?;
|
||||
|
||||
@@ -361,12 +367,20 @@ impl Vecs {
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
)?,
|
||||
indexes_to_supply: ComputedValueVecsFromHeight::forced_import(
|
||||
height_to_supply_value: ComputedHeightValueVecs::forced_import(
|
||||
path,
|
||||
&suffix("supply"),
|
||||
false,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
compute_dollars,
|
||||
)?,
|
||||
indexes_to_supply: ComputedValueVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&suffix("supply"),
|
||||
true,
|
||||
version + VERSION + Version::ONE,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
compute_dollars,
|
||||
)?,
|
||||
@@ -595,7 +609,15 @@ impl Vecs {
|
||||
)
|
||||
.unwrap()
|
||||
}),
|
||||
indexes_to_halved_supply: ComputedValueVecsFromHeight::forced_import(
|
||||
height_to_halved_supply_value: ComputedHeightValueVecs::forced_import(
|
||||
path,
|
||||
&suffix("halved_supply"),
|
||||
true,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
compute_dollars,
|
||||
)?,
|
||||
indexes_to_halved_supply: ComputedValueVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&suffix("halved_supply"),
|
||||
true,
|
||||
@@ -604,7 +626,6 @@ impl Vecs {
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
compute_dollars,
|
||||
)?,
|
||||
|
||||
height_to_negative_unrealized_loss: compute_dollars.then(|| {
|
||||
EagerVec::forced_import(
|
||||
path,
|
||||
@@ -687,7 +708,7 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_even"),
|
||||
false,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
compute_dollars,
|
||||
)
|
||||
@@ -698,7 +719,7 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_in_loss"),
|
||||
false,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
compute_dollars,
|
||||
)
|
||||
@@ -709,7 +730,7 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_in_profit"),
|
||||
false,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
compute_dollars,
|
||||
)
|
||||
@@ -719,7 +740,7 @@ impl Vecs {
|
||||
EagerVec::forced_import(
|
||||
path,
|
||||
&suffix("supply_even_relative_to_own_supply"),
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
)
|
||||
.unwrap()
|
||||
@@ -728,7 +749,7 @@ impl Vecs {
|
||||
EagerVec::forced_import(
|
||||
path,
|
||||
&suffix("supply_in_loss_relative_to_own_supply"),
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
)
|
||||
.unwrap()
|
||||
@@ -737,7 +758,7 @@ impl Vecs {
|
||||
EagerVec::forced_import(
|
||||
path,
|
||||
&suffix("supply_in_profit_relative_to_own_supply"),
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
)
|
||||
.unwrap()
|
||||
@@ -747,7 +768,7 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_even_relative_to_own_supply"),
|
||||
true,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)
|
||||
@@ -758,7 +779,7 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_in_loss_relative_to_own_supply"),
|
||||
true,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)
|
||||
@@ -769,7 +790,7 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_in_profit_relative_to_own_supply"),
|
||||
true,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)
|
||||
@@ -780,7 +801,7 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_relative_to_circulating_supply"),
|
||||
true,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)
|
||||
@@ -792,7 +813,7 @@ impl Vecs {
|
||||
EagerVec::forced_import(
|
||||
path,
|
||||
&suffix("supply_even_relative_to_circulating_supply"),
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
)
|
||||
.unwrap()
|
||||
@@ -803,7 +824,7 @@ impl Vecs {
|
||||
EagerVec::forced_import(
|
||||
path,
|
||||
&suffix("supply_in_loss_relative_to_circulating_supply"),
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
)
|
||||
.unwrap()
|
||||
@@ -814,7 +835,7 @@ impl Vecs {
|
||||
EagerVec::forced_import(
|
||||
path,
|
||||
&suffix("supply_in_profit_relative_to_circulating_supply"),
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
)
|
||||
.unwrap()
|
||||
@@ -826,7 +847,7 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_even_relative_to_circulating_supply"),
|
||||
true,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)
|
||||
@@ -839,7 +860,7 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_in_loss_relative_to_circulating_supply"),
|
||||
true,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)
|
||||
@@ -852,12 +873,44 @@ impl Vecs {
|
||||
path,
|
||||
&suffix("supply_in_profit_relative_to_circulating_supply"),
|
||||
true,
|
||||
version,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)
|
||||
.unwrap()
|
||||
}),
|
||||
height_to_satblocks_destroyed: EagerVec::forced_import(
|
||||
path,
|
||||
&suffix("satblocks_destroyed"),
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
)?,
|
||||
height_to_satdays_destroyed: EagerVec::forced_import(
|
||||
path,
|
||||
&suffix("satdays_destroyed"),
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
)?,
|
||||
indexes_to_coinblocks_destroyed: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
&suffix("coinblocks_destroyed"),
|
||||
true,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default()
|
||||
.add_sum()
|
||||
.add_cumulative(),
|
||||
)?,
|
||||
indexes_to_coindays_destroyed: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
&suffix("coindays_destroyed"),
|
||||
true,
|
||||
version + VERSION + Version::ZERO,
|
||||
format,
|
||||
StorableVecGeneatorOptions::default()
|
||||
.add_sum()
|
||||
.add_cumulative(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -911,6 +964,8 @@ impl Vecs {
|
||||
self.height_to_max_price_paid
|
||||
.as_ref()
|
||||
.map_or(usize::MAX, |v| v.len()),
|
||||
self.height_to_satdays_destroyed.len(),
|
||||
self.height_to_satblocks_destroyed.len(),
|
||||
]
|
||||
.into_iter()
|
||||
.map(Height::from)
|
||||
@@ -956,6 +1011,16 @@ impl Vecs {
|
||||
base_version + self.height_to_utxo_count.inner_version(),
|
||||
)?;
|
||||
|
||||
self.height_to_satblocks_destroyed
|
||||
.validate_computed_version_or_reset_file(
|
||||
base_version + self.height_to_satblocks_destroyed.inner_version(),
|
||||
)?;
|
||||
|
||||
self.height_to_satdays_destroyed
|
||||
.validate_computed_version_or_reset_file(
|
||||
base_version + self.height_to_satdays_destroyed.inner_version(),
|
||||
)?;
|
||||
|
||||
if let Some(height_to_realized_cap) = self.height_to_realized_cap.as_mut().as_mut() {
|
||||
height_to_realized_cap.validate_computed_version_or_reset_file(
|
||||
base_version + height_to_realized_cap.inner_version(),
|
||||
@@ -1175,6 +1240,18 @@ impl Vecs {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_satblocks_destroyed.forced_push_at(
|
||||
height,
|
||||
self.state.satblocks_destroyed,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_satdays_destroyed.forced_push_at(
|
||||
height,
|
||||
self.state.satdays_destroyed,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
if let Some(height_to_realized_cap) = self.height_to_realized_cap.as_mut() {
|
||||
let realized = self.state.realized.as_ref().unwrap_or_else(|| {
|
||||
dbg!((&self.state.realized, &self.state.supply));
|
||||
@@ -1301,8 +1378,9 @@ impl Vecs {
|
||||
|
||||
pub fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> {
|
||||
self.height_to_supply.safe_flush(exit)?;
|
||||
|
||||
self.height_to_utxo_count.safe_flush(exit)?;
|
||||
self.height_to_satdays_destroyed.safe_flush(exit)?;
|
||||
self.height_to_satblocks_destroyed.safe_flush(exit)?;
|
||||
|
||||
if let Some(height_to_realized_cap) = self.height_to_realized_cap.as_mut() {
|
||||
height_to_realized_cap.safe_flush(exit)?;
|
||||
@@ -1409,6 +1487,24 @@ impl Vecs {
|
||||
.as_slice(),
|
||||
exit,
|
||||
)?;
|
||||
self.height_to_satblocks_destroyed.compute_sum_of_others(
|
||||
starting_indexes.height,
|
||||
others
|
||||
.iter()
|
||||
.map(|v| &v.height_to_satblocks_destroyed)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
exit,
|
||||
)?;
|
||||
self.height_to_satdays_destroyed.compute_sum_of_others(
|
||||
starting_indexes.height,
|
||||
others
|
||||
.iter()
|
||||
.map(|v| &v.height_to_satdays_destroyed)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
if let Some(height_to_realized_cap) = &mut self.height_to_realized_cap {
|
||||
height_to_realized_cap.compute_sum_of_others(
|
||||
@@ -1675,13 +1771,37 @@ impl Vecs {
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
self.indexes_to_supply.compute_rest(
|
||||
self.height_to_supply_value.compute_rest(
|
||||
fetched,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.height_to_supply),
|
||||
)?;
|
||||
|
||||
self.indexes_to_supply.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
fetched,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.height_to_supply),
|
||||
|v, _, indexes, starting_indexes, exit| {
|
||||
let mut dateindex_to_height_count_iter =
|
||||
indexes.dateindex_to_height_count.into_iter();
|
||||
let mut height_to_supply_iter = self.height_to_supply.into_iter();
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&indexes.dateindex_to_first_height,
|
||||
|(i, height, ..)| {
|
||||
let count = dateindex_to_height_count_iter.unwrap_get_inner(i);
|
||||
if count == StoredUsize::default() {
|
||||
unreachable!()
|
||||
}
|
||||
let supply = height_to_supply_iter.unwrap_get_inner(height + (*count - 1));
|
||||
(i, supply)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_utxo_count.compute_rest(
|
||||
@@ -1691,6 +1811,22 @@ impl Vecs {
|
||||
Some(&self.height_to_utxo_count),
|
||||
)?;
|
||||
|
||||
self.height_to_halved_supply_value.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
fetched,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.height_to_supply,
|
||||
|(h, v, ..)| (h, v / 2),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_halved_supply.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
@@ -1699,9 +1835,37 @@ impl Vecs {
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_supply.sats.dateindex.as_ref().unwrap(),
|
||||
|(i, sats, ..)| (i, sats / 2),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_coinblocks_destroyed.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_from_sats(
|
||||
starting_indexes.height,
|
||||
&self.height_to_supply,
|
||||
|(h, sats, ..)| (h, sats / 2),
|
||||
&self.height_to_satblocks_destroyed,
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_coindays_destroyed.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_from_sats(
|
||||
starting_indexes.height,
|
||||
&self.height_to_satdays_destroyed,
|
||||
exit,
|
||||
)
|
||||
},
|
||||
@@ -1718,8 +1882,8 @@ impl Vecs {
|
||||
fetched: Option<&fetched::Vecs>,
|
||||
starting_indexes: &Indexes,
|
||||
market: &market::Vecs,
|
||||
height_to_supply: &impl AnyIterableVec<Height, Sats>,
|
||||
dateindex_to_supply: &impl AnyIterableVec<DateIndex, Sats>,
|
||||
height_to_supply: &impl AnyIterableVec<Height, Bitcoin>,
|
||||
dateindex_to_supply: &impl AnyIterableVec<DateIndex, Bitcoin>,
|
||||
height_to_realized_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
@@ -1735,7 +1899,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_percentage(
|
||||
starting_indexes.height,
|
||||
&self.height_to_supply,
|
||||
&self.height_to_supply_value.bitcoin,
|
||||
height_to_supply,
|
||||
exit,
|
||||
)
|
||||
@@ -1763,7 +1927,7 @@ impl Vecs {
|
||||
vec.compute_divide(
|
||||
starting_indexes.height,
|
||||
self.height_to_realized_cap.as_ref().unwrap(),
|
||||
self.indexes_to_supply.bitcoin.height.as_ref().unwrap(),
|
||||
&self.height_to_supply_value.bitcoin,
|
||||
exit,
|
||||
)
|
||||
},
|
||||
@@ -2213,7 +2377,7 @@ impl Vecs {
|
||||
v.compute_percentage(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_supply_even.as_ref().unwrap(),
|
||||
self.indexes_to_supply.sats.dateindex.unwrap_last(),
|
||||
self.indexes_to_supply.sats.dateindex.as_ref().unwrap(),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
@@ -2230,7 +2394,7 @@ impl Vecs {
|
||||
v.compute_percentage(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_supply_even.as_ref().unwrap(),
|
||||
self.indexes_to_supply.sats.dateindex.unwrap_last(),
|
||||
self.indexes_to_supply.sats.dateindex.as_ref().unwrap(),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
@@ -2247,7 +2411,7 @@ impl Vecs {
|
||||
v.compute_percentage(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_supply_even.as_ref().unwrap(),
|
||||
self.indexes_to_supply.sats.dateindex.unwrap_last(),
|
||||
self.indexes_to_supply.sats.dateindex.as_ref().unwrap(),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
@@ -2259,7 +2423,7 @@ impl Vecs {
|
||||
{
|
||||
height_to_supply_even_relative_to_circulating_supply.compute_percentage(
|
||||
starting_indexes.height,
|
||||
self.height_to_supply_even.as_ref().unwrap(),
|
||||
&self.height_to_supply_even_value.as_ref().unwrap().bitcoin,
|
||||
height_to_supply,
|
||||
exit,
|
||||
)?;
|
||||
@@ -2268,7 +2432,11 @@ impl Vecs {
|
||||
.unwrap()
|
||||
.compute_percentage(
|
||||
starting_indexes.height,
|
||||
self.height_to_supply_in_loss.as_ref().unwrap(),
|
||||
&self
|
||||
.height_to_supply_in_loss_value
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.bitcoin,
|
||||
height_to_supply,
|
||||
exit,
|
||||
)?;
|
||||
@@ -2277,7 +2445,11 @@ impl Vecs {
|
||||
.unwrap()
|
||||
.compute_percentage(
|
||||
starting_indexes.height,
|
||||
self.height_to_supply_in_profit.as_ref().unwrap(),
|
||||
&self
|
||||
.height_to_supply_in_profit_value
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.bitcoin,
|
||||
height_to_supply,
|
||||
exit,
|
||||
)?;
|
||||
@@ -2292,7 +2464,13 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_percentage(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_supply_even.as_ref().unwrap(),
|
||||
self.indexes_to_supply_even
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.bitcoin
|
||||
.dateindex
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
dateindex_to_supply,
|
||||
exit,
|
||||
)
|
||||
@@ -2309,7 +2487,13 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_percentage(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_supply_in_loss.as_ref().unwrap(),
|
||||
self.indexes_to_supply_in_loss
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.bitcoin
|
||||
.dateindex
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
dateindex_to_supply,
|
||||
exit,
|
||||
)
|
||||
@@ -2326,7 +2510,13 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_percentage(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_supply_in_profit.as_ref().unwrap(),
|
||||
self.indexes_to_supply_in_profit
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.bitcoin
|
||||
.dateindex
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
dateindex_to_supply,
|
||||
exit,
|
||||
)
|
||||
@@ -2343,10 +2533,14 @@ impl Vecs {
|
||||
vec![
|
||||
&self.height_to_supply as &dyn AnyCollectableVec,
|
||||
&self.height_to_utxo_count,
|
||||
&self.height_to_satblocks_destroyed,
|
||||
&self.height_to_satdays_destroyed,
|
||||
],
|
||||
self.height_to_realized_cap
|
||||
.as_ref()
|
||||
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
|
||||
self.height_to_supply_value.vecs(),
|
||||
self.height_to_halved_supply_value.vecs(),
|
||||
self.indexes_to_supply.vecs(),
|
||||
self.indexes_to_utxo_count.vecs(),
|
||||
self.indexes_to_realized_cap
|
||||
@@ -2542,6 +2736,8 @@ impl Vecs {
|
||||
self.indexes_to_supply_in_profit_relative_to_circulating_supply
|
||||
.as_ref()
|
||||
.map_or(vec![], |v| v.vecs()),
|
||||
self.indexes_to_coinblocks_destroyed.vecs(),
|
||||
self.indexes_to_coindays_destroyed.vecs(),
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
|
||||
@@ -29,7 +29,7 @@ use super::{
|
||||
pub mod cohort;
|
||||
mod outputs;
|
||||
|
||||
const VERSION: Version = Version::new(9);
|
||||
const VERSION: Version = Version::new(5);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
@@ -40,10 +40,6 @@ pub struct Vecs {
|
||||
pub indexes_to_unspendable_supply: ComputedValueVecsFromHeight,
|
||||
pub height_to_opreturn_supply: EagerVec<Height, Sats>,
|
||||
pub indexes_to_opreturn_supply: ComputedValueVecsFromHeight,
|
||||
// pub height_to_satdays_destroyed: EagerVec<Height, Sats>,
|
||||
// pub indexes_to_satdays_destroyed: ComputedValueVecsFromHeight,
|
||||
// pub height_to_satblocks_destroyed: EagerVec<Height, Sats>,
|
||||
// pub indexes_to_satblocks_destroyed: ComputedValueVecsFromHeight,
|
||||
utxos_vecs: Outputs<(OutputFilter, cohort::Vecs)>,
|
||||
}
|
||||
|
||||
@@ -102,36 +98,6 @@ impl Vecs {
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
compute_dollars,
|
||||
)?,
|
||||
// height_to_satdays_destroyed: EagerVec::forced_import(
|
||||
// path,
|
||||
// "satdays_destroyed",
|
||||
// version,
|
||||
// format,
|
||||
// )?,
|
||||
// indexes_to_satdays_destroyed: ComputedValueVecsFromHeight::forced_import(
|
||||
// path,
|
||||
// "satdays_destroyed",
|
||||
// false,
|
||||
// version + VERSION + Version::ZERO,
|
||||
// format,
|
||||
// StorableVecGeneatorOptions::default().add_last(),
|
||||
// compute_dollars,
|
||||
// )?,
|
||||
// height_to_satblocks_destroyed: EagerVec::forced_import(
|
||||
// path,
|
||||
// "satblocks_destroyed",
|
||||
// version,
|
||||
// format,
|
||||
// )?,
|
||||
// indexes_to_satblocks_destroyed: ComputedValueVecsFromHeight::forced_import(
|
||||
// path,
|
||||
// "satblocks_destroyed",
|
||||
// false,
|
||||
// version + VERSION + Version::ZERO,
|
||||
// format,
|
||||
// StorableVecGeneatorOptions::default().add_last(),
|
||||
// compute_dollars,
|
||||
// )?,
|
||||
utxos_vecs: {
|
||||
Outputs::<(OutputFilter, cohort::Vecs)>::from(Outputs {
|
||||
all: cohort::Vecs::forced_import(
|
||||
@@ -603,9 +569,9 @@ impl Vecs {
|
||||
&stores_path,
|
||||
true,
|
||||
)?,
|
||||
_1m_to_3m: cohort::Vecs::forced_import(
|
||||
_1m_to_2m: cohort::Vecs::forced_import(
|
||||
path,
|
||||
Some("from_1m_to_3m"),
|
||||
Some("from_1m_to_2m"),
|
||||
_computation,
|
||||
format,
|
||||
version + VERSION + Version::ZERO,
|
||||
@@ -614,9 +580,42 @@ impl Vecs {
|
||||
&stores_path,
|
||||
true,
|
||||
)?,
|
||||
_3m_to_6m: cohort::Vecs::forced_import(
|
||||
_2m_to_3m: cohort::Vecs::forced_import(
|
||||
path,
|
||||
Some("from_3m_to_6m"),
|
||||
Some("from_2m_to_3m"),
|
||||
_computation,
|
||||
format,
|
||||
version + VERSION + Version::ZERO,
|
||||
fetched,
|
||||
keyspace,
|
||||
&stores_path,
|
||||
true,
|
||||
)?,
|
||||
_3m_to_4m: cohort::Vecs::forced_import(
|
||||
path,
|
||||
Some("from_3m_to_4m"),
|
||||
_computation,
|
||||
format,
|
||||
version + VERSION + Version::ZERO,
|
||||
fetched,
|
||||
keyspace,
|
||||
&stores_path,
|
||||
true,
|
||||
)?,
|
||||
_4m_to_5m: cohort::Vecs::forced_import(
|
||||
path,
|
||||
Some("from_4m_to_5m"),
|
||||
_computation,
|
||||
format,
|
||||
version + VERSION + Version::ZERO,
|
||||
fetched,
|
||||
keyspace,
|
||||
&stores_path,
|
||||
true,
|
||||
)?,
|
||||
_5m_to_6m: cohort::Vecs::forced_import(
|
||||
path,
|
||||
Some("from_5m_to_6m"),
|
||||
_computation,
|
||||
format,
|
||||
version + VERSION + Version::ZERO,
|
||||
@@ -680,9 +679,9 @@ impl Vecs {
|
||||
&stores_path,
|
||||
true,
|
||||
)?,
|
||||
_5y_to_7y: cohort::Vecs::forced_import(
|
||||
_5y_to_6y: cohort::Vecs::forced_import(
|
||||
path,
|
||||
Some("from_5y_to_7y"),
|
||||
Some("from_5y_to_6y"),
|
||||
_computation,
|
||||
format,
|
||||
version + VERSION + Version::ZERO,
|
||||
@@ -691,9 +690,31 @@ impl Vecs {
|
||||
&stores_path,
|
||||
true,
|
||||
)?,
|
||||
_7y_to_10y: cohort::Vecs::forced_import(
|
||||
_6y_to_7y: cohort::Vecs::forced_import(
|
||||
path,
|
||||
Some("from_7y_to_10y"),
|
||||
Some("from_6y_to_7y"),
|
||||
_computation,
|
||||
format,
|
||||
version + VERSION + Version::ZERO,
|
||||
fetched,
|
||||
keyspace,
|
||||
&stores_path,
|
||||
true,
|
||||
)?,
|
||||
_7y_to_8y: cohort::Vecs::forced_import(
|
||||
path,
|
||||
Some("from_7y_to_8y"),
|
||||
_computation,
|
||||
format,
|
||||
version + VERSION + Version::ZERO,
|
||||
fetched,
|
||||
keyspace,
|
||||
&stores_path,
|
||||
true,
|
||||
)?,
|
||||
_8y_to_10y: cohort::Vecs::forced_import(
|
||||
path,
|
||||
Some("from_8y_to_10y"),
|
||||
_computation,
|
||||
format,
|
||||
version + VERSION + Version::ZERO,
|
||||
@@ -1377,14 +1398,6 @@ impl Vecs {
|
||||
.validate_computed_version_or_reset_file(
|
||||
base_version + self.height_to_opreturn_supply.inner_version(),
|
||||
)?;
|
||||
// self.height_to_satblocks_destroyed
|
||||
// .validate_computed_version_or_reset_file(
|
||||
// base_version + self.height_to_satblocks_destroyed.inner_version(),
|
||||
// )?;
|
||||
// self.height_to_satdays_destroyed
|
||||
// .validate_computed_version_or_reset_file(
|
||||
// base_version + self.height_to_satdays_destroyed.inner_version(),
|
||||
// )?;
|
||||
|
||||
let mut chain_state: Vec<BlockState>;
|
||||
let mut chain_state_starting_height = Height::from(self.chain_state.len());
|
||||
@@ -1437,8 +1450,6 @@ impl Vecs {
|
||||
.min(stateful_starting_height)
|
||||
.min(Height::from(self.height_to_unspendable_supply.len()))
|
||||
.min(Height::from(self.height_to_opreturn_supply.len()));
|
||||
// .min(Height::from(self.height_to_satblocks_destroyed.len()));
|
||||
// .min(Height::from(self.height_to_satdays_destroyed.len()));
|
||||
|
||||
// ---
|
||||
// INIT
|
||||
@@ -1462,20 +1473,6 @@ impl Vecs {
|
||||
} else {
|
||||
Sats::ZERO
|
||||
};
|
||||
// let mut satblocks_destroyed = if let Some(prev_height) = starting_height.decremented() {
|
||||
// self.height_to_satblocks_destroyed
|
||||
// .into_iter()
|
||||
// .unwrap_get_inner(prev_height)
|
||||
// } else {
|
||||
// Sats::ZERO
|
||||
// };
|
||||
// let mut satdays_destroyed = if let Some(prev_height) = starting_height.decremented() {
|
||||
// self.height_to_satdays_destroyed
|
||||
// .into_iter()
|
||||
// .unwrap_get_inner(prev_height)
|
||||
// } else {
|
||||
// Sats::ZERO
|
||||
// };
|
||||
|
||||
let mut height = starting_height;
|
||||
starting_indexes.update_from_height(height, indexes);
|
||||
@@ -1717,18 +1714,16 @@ impl Vecs {
|
||||
.try_for_each(|(_, v)| {
|
||||
v.compute_rest_part1(indexer, indexes, fetched, &starting_indexes, exit)
|
||||
})?;
|
||||
let height_to_supply = self.utxos_vecs.all.1.height_to_supply.clone();
|
||||
let height_to_supply = self.utxos_vecs.all.1.height_to_supply_value.bitcoin.clone();
|
||||
let dateindex_to_supply = self
|
||||
.utxos_vecs
|
||||
.all
|
||||
.1
|
||||
.indexes_to_supply
|
||||
.sats
|
||||
.bitcoin
|
||||
.dateindex
|
||||
.unwrap_last()
|
||||
.clone();
|
||||
let height_to_realized_cap = self.utxos_vecs.all.1.height_to_realized_cap.clone();
|
||||
let height_to_realized_cap = height_to_realized_cap.as_ref();
|
||||
self.utxos_vecs
|
||||
.as_mut_vecs()
|
||||
.par_iter_mut()
|
||||
@@ -1740,8 +1735,8 @@ impl Vecs {
|
||||
&starting_indexes,
|
||||
market,
|
||||
&height_to_supply,
|
||||
&dateindex_to_supply,
|
||||
height_to_realized_cap,
|
||||
dateindex_to_supply.as_ref().unwrap(),
|
||||
height_to_realized_cap.as_ref(),
|
||||
exit,
|
||||
)
|
||||
})?;
|
||||
@@ -1761,22 +1756,6 @@ impl Vecs {
|
||||
exit,
|
||||
Some(&self.height_to_opreturn_supply),
|
||||
)?;
|
||||
// self.indexes_to_satblocks_destroyed.compute_rest(
|
||||
// indexer,
|
||||
// indexes,
|
||||
// fetched,
|
||||
// &starting_indexes,
|
||||
// exit,
|
||||
// Some(&self.height_to_satblocks_destroyed),
|
||||
// )?;
|
||||
// self.indexes_to_satdays_destroyed.compute_rest(
|
||||
// indexer,
|
||||
// indexes,
|
||||
// fetched,
|
||||
// &starting_indexes,
|
||||
// exit,
|
||||
// Some(&self.height_to_satdays_destroyed),
|
||||
// )?;
|
||||
|
||||
exit.release();
|
||||
|
||||
@@ -1795,8 +1774,6 @@ impl Vecs {
|
||||
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))?;
|
||||
self.height_to_unspendable_supply.safe_flush(exit)?;
|
||||
self.height_to_opreturn_supply.safe_flush(exit)?;
|
||||
// self.height_to_satblocks_destroyed.safe_flush(exit)?;
|
||||
// self.height_to_satdays_destroyed.safe_flush(exit)?;
|
||||
|
||||
self.chain_state.truncate_if_needed(Height::ZERO)?;
|
||||
chain_state.iter().for_each(|block_state| {
|
||||
@@ -1820,16 +1797,6 @@ impl Vecs {
|
||||
&self.height_to_unspendable_supply,
|
||||
&self.height_to_opreturn_supply,
|
||||
],
|
||||
// self.indexes_to_satblocks_destroyed.vecs(),
|
||||
// vec![
|
||||
// &self.height_to_unspendable_supply,
|
||||
// &self.height_to_satblocks_destroyed,
|
||||
// ],
|
||||
// self.indexes_to_satdays_destroyed.vecs(),
|
||||
// vec![
|
||||
// &self.height_to_unspendable_supply,
|
||||
// &self.height_to_satdays_destroyed,
|
||||
// ],
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
|
||||
@@ -72,10 +72,16 @@ impl OutputCohorts for Outputs<(OutputFilter, cohort::Vecs)> {
|
||||
let block_state = chain_state.get(height.unwrap_to_usize()).unwrap();
|
||||
let prev_price = block_state.price;
|
||||
|
||||
let blocks_old = chain_state.len() - 1 - height.unwrap_to_usize();
|
||||
|
||||
let days_old = block_state
|
||||
.timestamp
|
||||
.difference_in_days_between(last_timestamp);
|
||||
|
||||
let days_old_foat = block_state
|
||||
.timestamp
|
||||
.difference_in_days_between_float(last_timestamp);
|
||||
|
||||
let older_than_hour =
|
||||
jiff::Timestamp::from(last_timestamp.checked_sub(block_state.timestamp).unwrap())
|
||||
.as_second()
|
||||
@@ -95,6 +101,8 @@ impl OutputCohorts for Outputs<(OutputFilter, cohort::Vecs)> {
|
||||
&sent.spendable_supply,
|
||||
current_price,
|
||||
prev_price,
|
||||
blocks_old,
|
||||
days_old_foat,
|
||||
older_than_hour,
|
||||
);
|
||||
});
|
||||
@@ -105,6 +113,8 @@ impl OutputCohorts for Outputs<(OutputFilter, cohort::Vecs)> {
|
||||
supply_state,
|
||||
current_price,
|
||||
prev_price,
|
||||
blocks_old,
|
||||
days_old_foat,
|
||||
older_than_hour,
|
||||
)
|
||||
},
|
||||
@@ -117,6 +127,8 @@ impl OutputCohorts for Outputs<(OutputFilter, cohort::Vecs)> {
|
||||
&supply_state,
|
||||
current_price,
|
||||
prev_price,
|
||||
blocks_old,
|
||||
days_old_foat,
|
||||
older_than_hour,
|
||||
);
|
||||
});
|
||||
@@ -159,93 +171,86 @@ impl OutputCohorts for Outputs<(OutputFilter, cohort::Vecs)> {
|
||||
}
|
||||
|
||||
fn compute_overlaping_vecs(&mut self, starting_indexes: &Indexes, exit: &Exit) -> Result<()> {
|
||||
self.all
|
||||
.1
|
||||
.compute_from_stateful(starting_indexes, &self.by_epoch.vecs(), exit)?;
|
||||
let by_date_range = self.by_date_range.as_vec();
|
||||
let by_size_range = self.by_size_range.as_vec();
|
||||
|
||||
self.by_from_date
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.try_for_each(|(filter, vecs)| {
|
||||
vecs.compute_from_stateful(
|
||||
starting_indexes,
|
||||
self.by_date_range
|
||||
.as_vec()
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
exit,
|
||||
)
|
||||
})?;
|
||||
|
||||
self.by_up_to_date
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.try_for_each(|(filter, vecs)| {
|
||||
vecs.compute_from_stateful(
|
||||
starting_indexes,
|
||||
self.by_date_range
|
||||
.as_vec()
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
exit,
|
||||
)
|
||||
})?;
|
||||
|
||||
self.by_term
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.try_for_each(|(filter, vecs)| {
|
||||
vecs.compute_from_stateful(
|
||||
starting_indexes,
|
||||
self.by_date_range
|
||||
.as_vec()
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
exit,
|
||||
)
|
||||
})?;
|
||||
|
||||
self.by_up_to_size
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.try_for_each(|(filter, vecs)| {
|
||||
vecs.compute_from_stateful(
|
||||
starting_indexes,
|
||||
self.by_date_range
|
||||
.as_vec()
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
exit,
|
||||
)
|
||||
})?;
|
||||
|
||||
self.by_from_size
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.try_for_each(|(filter, vecs)| {
|
||||
vecs.compute_from_stateful(
|
||||
starting_indexes,
|
||||
self.by_size_range
|
||||
.as_vec()
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
exit,
|
||||
)
|
||||
})
|
||||
[
|
||||
vec![(&mut self.all.1, self.by_epoch.vecs().to_vec())],
|
||||
self.by_from_date
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.map(|(filter, vecs)| {
|
||||
(
|
||||
vecs,
|
||||
by_date_range
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
self.by_up_to_date
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.map(|(filter, vecs)| {
|
||||
(
|
||||
vecs,
|
||||
by_date_range
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
self.by_term
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.map(|(filter, vecs)| {
|
||||
(
|
||||
vecs,
|
||||
by_date_range
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
self.by_from_size
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.map(|(filter, vecs)| {
|
||||
(
|
||||
vecs,
|
||||
by_size_range
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
self.by_up_to_size
|
||||
.as_mut_vec()
|
||||
.into_iter()
|
||||
.map(|(filter, vecs)| {
|
||||
(
|
||||
vecs,
|
||||
by_size_range
|
||||
.into_iter()
|
||||
.filter(|(other, _)| filter.includes(other))
|
||||
.map(|(_, v)| v)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
]
|
||||
.into_par_iter()
|
||||
.flatten()
|
||||
.try_for_each(|(vecs, stateful)| {
|
||||
vecs.compute_from_stateful(starting_indexes, &stateful, exit)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ use std::{
|
||||
use serde::Serialize;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
use super::{Sats, StoredF64};
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize)]
|
||||
@@ -25,6 +27,20 @@ impl Mul for Bitcoin {
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<usize> for Bitcoin {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: usize) -> Self::Output {
|
||||
Self::from(Sats::from(self) * rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<Bitcoin> for Bitcoin {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: Bitcoin) -> Self::Output {
|
||||
Self::from(Sats::from(self) / Sats::from(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<usize> for Bitcoin {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: usize) -> Self::Output {
|
||||
@@ -93,3 +109,9 @@ impl Ord for Bitcoin {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CheckedSub<usize> for Bitcoin {
|
||||
fn checked_sub(self, rhs: usize) -> Option<Self> {
|
||||
Some(Self(self.0 - rhs as f64))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{CheckedSub, Sats};
|
||||
use crate::{Bitcoin, CheckedSub, Sats};
|
||||
|
||||
#[derive(
|
||||
Debug, Deref, Default, Clone, Copy, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize,
|
||||
@@ -102,3 +102,9 @@ impl From<Sats> for StoredF64 {
|
||||
Self(u64::from(value) as f64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Bitcoin> for StoredF64 {
|
||||
fn from(value: Bitcoin) -> Self {
|
||||
Self(f64::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,19 @@ impl Timestamp {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn difference_in_days_between_float(&self, other: Self) -> f64 {
|
||||
match self.cmp(&other) {
|
||||
Ordering::Equal => 0.0,
|
||||
Ordering::Greater => other.difference_in_days_between_float(*self),
|
||||
Ordering::Less => {
|
||||
jiff::Timestamp::from(*self)
|
||||
.duration_until(jiff::Timestamp::from(other))
|
||||
.as_secs() as f64
|
||||
/ ONE_DAY_IN_SEC as f64
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Timestamp {
|
||||
|
||||
@@ -8,11 +8,11 @@ fn main() -> color_eyre::Result<()> {
|
||||
|
||||
let mut fetcher = Fetcher::import(None)?;
|
||||
|
||||
dbg!(fetcher.get_date(Date::new(2025, 1, 1))?);
|
||||
dbg!(fetcher.get_date(Date::new(2025, 6, 5))?);
|
||||
dbg!(fetcher.get_height(
|
||||
881_000_u32.into(),
|
||||
1740683986_u32.into(),
|
||||
Some(1740683000_u32.into())
|
||||
899911_u32.into(),
|
||||
1749133056_u32.into(),
|
||||
Some(1749132055_u32.into())
|
||||
)?);
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -95,7 +95,7 @@ impl Binance {
|
||||
}
|
||||
|
||||
pub fn fetch_1d() -> color_eyre::Result<BTreeMap<Date, OHLCCents>> {
|
||||
info!("Fetching daily prices from Kraken...");
|
||||
info!("Fetching daily prices from Binance...");
|
||||
|
||||
retry(
|
||||
|_| Self::json_to_date_to_ohlc(&minreq::get(Self::url("interval=1d")).send()?.json()?),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
mod binance;
|
||||
mod kibo;
|
||||
mod kraken;
|
||||
// mod kraken;
|
||||
mod retry;
|
||||
|
||||
pub use binance::*;
|
||||
pub use kibo::*;
|
||||
pub use kraken::*;
|
||||
// pub use kraken::*;
|
||||
use retry::*;
|
||||
|
||||
@@ -18,7 +18,7 @@ const TRIES: usize = 12 * 60 * 2;
|
||||
#[derive(Clone)]
|
||||
pub struct Fetcher {
|
||||
binance: Binance,
|
||||
kraken: Kraken,
|
||||
// kraken: Kraken,
|
||||
kibo: Kibo,
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ impl Fetcher {
|
||||
|
||||
Ok(Self {
|
||||
binance: Binance::init(hars_path),
|
||||
kraken: Kraken::default(),
|
||||
// kraken: Kraken::default(),
|
||||
kibo: Kibo::default(),
|
||||
})
|
||||
}
|
||||
@@ -40,12 +40,8 @@ impl Fetcher {
|
||||
}
|
||||
|
||||
fn get_date_(&mut self, date: Date, tries: usize) -> color_eyre::Result<OHLCCents> {
|
||||
self.kraken
|
||||
self.binance
|
||||
.get_from_1d(&date)
|
||||
.or_else(|_| {
|
||||
// eprintln!("{e}");
|
||||
self.binance.get_from_1d(&date)
|
||||
})
|
||||
.or_else(|_| {
|
||||
// eprintln!("{e}");
|
||||
self.kibo.get_from_date(&date)
|
||||
@@ -89,33 +85,36 @@ impl Fetcher {
|
||||
let previous_timestamp = previous_timestamp.map(|t| t.floor_seconds());
|
||||
|
||||
let ohlc = self
|
||||
.kraken
|
||||
.binance
|
||||
.get_from_1mn(timestamp, previous_timestamp)
|
||||
.unwrap_or_else(|_| {
|
||||
// eprintln!("{e}");
|
||||
self.binance
|
||||
.get_from_1mn(timestamp, previous_timestamp)
|
||||
.unwrap_or_else(|_| {
|
||||
// eprintln!("{e}");
|
||||
self.kibo.get_from_height(height).unwrap_or_else(|_| {
|
||||
sleep(Duration::from_secs(30));
|
||||
.unwrap_or_else(|_report| {
|
||||
// eprintln!("{_report}");
|
||||
// self.kraken
|
||||
// .get_from_1mn(timestamp, previous_timestamp)
|
||||
// .unwrap_or_else(|_report| {
|
||||
// // eprintln!("{_report}");
|
||||
self.kibo.get_from_height(height).unwrap_or_else(|_report| {
|
||||
// eprintln!("{_report}");
|
||||
|
||||
if tries < TRIES {
|
||||
self.clear();
|
||||
sleep(Duration::from_secs(30));
|
||||
|
||||
info!("Retrying to fetch height prices...");
|
||||
if tries < TRIES {
|
||||
self.clear();
|
||||
|
||||
return self
|
||||
.get_height_(height, timestamp, previous_timestamp, tries + 1)
|
||||
.unwrap();
|
||||
}
|
||||
info!("Retrying to fetch height prices...");
|
||||
// dbg!((height, timestamp, previous_timestamp));
|
||||
|
||||
info!("Failed to fetch height prices");
|
||||
return self
|
||||
.get_height_(height, timestamp, previous_timestamp, tries + 1)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let date = Date::from(timestamp);
|
||||
// eprintln!("{e}");
|
||||
panic!(
|
||||
"
|
||||
info!("Failed to fetch height prices");
|
||||
|
||||
let date = Date::from(timestamp);
|
||||
// eprintln!("{e}");
|
||||
panic!(
|
||||
"
|
||||
Can't find the price for: height: {height} - date: {date}
|
||||
1mn APIs are limited to the last 16 hours for Binance's and the last 10 hours for Kraken's
|
||||
How to fix this:
|
||||
@@ -130,9 +129,9 @@ How to fix this:
|
||||
8. Export to a har file (if there is no explicit button, click on the cog button)
|
||||
9. Move the file to 'parser/imports/binance.har'
|
||||
"
|
||||
)
|
||||
})
|
||||
})
|
||||
)
|
||||
})
|
||||
// })
|
||||
});
|
||||
|
||||
Ok(ohlc)
|
||||
@@ -183,6 +182,6 @@ How to fix this:
|
||||
pub fn clear(&mut self) {
|
||||
self.binance.clear();
|
||||
self.kibo.clear();
|
||||
self.kraken.clear();
|
||||
// self.kraken.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ impl<'a> VecTrees<'a> {
|
||||
|| s.ends_with("relative")
|
||||
|| s.starts_with("from")
|
||||
|| s == &"cumulative_up"
|
||||
|| s.starts_with("cumulative_start")
|
||||
|| s.starts_with("cumulative_from")
|
||||
}))
|
||||
&& !(split.len() == 4
|
||||
|
||||
@@ -12,6 +12,8 @@ use super::{RealizedState, SupplyState};
|
||||
pub struct CohortState {
|
||||
pub supply: SupplyState,
|
||||
pub realized: Option<RealizedState>,
|
||||
pub satblocks_destroyed: Sats,
|
||||
pub satdays_destroyed: Sats,
|
||||
pub price_to_amount: Store<Dollars, Sats>,
|
||||
}
|
||||
|
||||
@@ -26,6 +28,8 @@ impl CohortState {
|
||||
Ok(Self {
|
||||
supply: SupplyState::default(),
|
||||
realized: compute_dollars.then_some(RealizedState::NAN),
|
||||
satblocks_destroyed: Sats::ZERO,
|
||||
satdays_destroyed: Sats::ZERO,
|
||||
price_to_amount: Store::import(
|
||||
keyspace,
|
||||
path,
|
||||
@@ -37,6 +41,8 @@ impl CohortState {
|
||||
}
|
||||
|
||||
pub fn reset_single_iteration_values(&mut self) {
|
||||
self.satdays_destroyed = Sats::ZERO;
|
||||
self.satblocks_destroyed = Sats::ZERO;
|
||||
if let Some(realized) = self.realized.as_mut() {
|
||||
realized.reset_single_iteration_values();
|
||||
}
|
||||
@@ -74,9 +80,17 @@ impl CohortState {
|
||||
supply_state: &SupplyState,
|
||||
current_price: Option<Dollars>,
|
||||
prev_price: Option<Dollars>,
|
||||
blocks_old: usize,
|
||||
days_old: f64,
|
||||
older_than_hour: bool,
|
||||
) {
|
||||
self.supply -= supply_state;
|
||||
|
||||
self.satblocks_destroyed += supply_state.value * blocks_old;
|
||||
|
||||
self.satdays_destroyed +=
|
||||
Sats::from((u64::from(supply_state.value) as f64 * days_old).floor() as u64);
|
||||
|
||||
if let Some(realized) = self.realized.as_mut() {
|
||||
let current_price = current_price.unwrap();
|
||||
let prev_price = prev_price.unwrap();
|
||||
|
||||
@@ -5,15 +5,20 @@ pub struct OutputsByDateRange<T> {
|
||||
pub start_to_1d: T,
|
||||
pub _1d_to_1w: T,
|
||||
pub _1w_to_1m: T,
|
||||
pub _1m_to_3m: T,
|
||||
pub _3m_to_6m: T,
|
||||
pub _1m_to_2m: T,
|
||||
pub _2m_to_3m: T,
|
||||
pub _3m_to_4m: T,
|
||||
pub _4m_to_5m: T,
|
||||
pub _5m_to_6m: T,
|
||||
pub _6m_to_1y: T,
|
||||
pub _1y_to_2y: T,
|
||||
pub _2y_to_3y: T,
|
||||
pub _3y_to_4y: T,
|
||||
pub _4y_to_5y: T,
|
||||
pub _5y_to_7y: T,
|
||||
pub _7y_to_10y: T,
|
||||
pub _5y_to_6y: T,
|
||||
pub _6y_to_7y: T,
|
||||
pub _7y_to_8y: T,
|
||||
pub _8y_to_10y: T,
|
||||
pub _10y_to_15y: T,
|
||||
pub _15y_to_end: T,
|
||||
}
|
||||
@@ -24,15 +29,20 @@ impl<T> From<OutputsByDateRange<T>> for OutputsByDateRange<(OutputFilter, T)> {
|
||||
start_to_1d: (OutputFilter::To(1), value.start_to_1d),
|
||||
_1d_to_1w: (OutputFilter::Range(1..7), value._1d_to_1w),
|
||||
_1w_to_1m: (OutputFilter::Range(7..30), value._1w_to_1m),
|
||||
_1m_to_3m: (OutputFilter::Range(30..3 * 30), value._1m_to_3m),
|
||||
_3m_to_6m: (OutputFilter::Range(3 * 30..6 * 30), value._3m_to_6m),
|
||||
_1m_to_2m: (OutputFilter::Range(30..2 * 30), value._1m_to_2m),
|
||||
_2m_to_3m: (OutputFilter::Range(2 * 30..3 * 30), value._2m_to_3m),
|
||||
_3m_to_4m: (OutputFilter::Range(3 * 30..4 * 30), value._3m_to_4m),
|
||||
_4m_to_5m: (OutputFilter::Range(4 * 30..5 * 30), value._4m_to_5m),
|
||||
_5m_to_6m: (OutputFilter::Range(5 * 30..6 * 30), value._5m_to_6m),
|
||||
_6m_to_1y: (OutputFilter::Range(6 * 30..365), value._6m_to_1y),
|
||||
_1y_to_2y: (OutputFilter::Range(365..2 * 365), value._1y_to_2y),
|
||||
_2y_to_3y: (OutputFilter::Range(2 * 365..3 * 365), value._2y_to_3y),
|
||||
_3y_to_4y: (OutputFilter::Range(3 * 365..4 * 365), value._3y_to_4y),
|
||||
_4y_to_5y: (OutputFilter::Range(4 * 365..5 * 365), value._4y_to_5y),
|
||||
_5y_to_7y: (OutputFilter::Range(5 * 365..7 * 365), value._5y_to_7y),
|
||||
_7y_to_10y: (OutputFilter::Range(7 * 365..10 * 365), value._7y_to_10y),
|
||||
_5y_to_6y: (OutputFilter::Range(5 * 365..6 * 365), value._5y_to_6y),
|
||||
_6y_to_7y: (OutputFilter::Range(6 * 365..7 * 365), value._6y_to_7y),
|
||||
_7y_to_8y: (OutputFilter::Range(7 * 365..8 * 365), value._7y_to_8y),
|
||||
_8y_to_10y: (OutputFilter::Range(7 * 365..10 * 365), value._8y_to_10y),
|
||||
_10y_to_15y: (OutputFilter::Range(10 * 365..15 * 365), value._10y_to_15y),
|
||||
_15y_to_end: (OutputFilter::From(15 * 365), value._15y_to_end),
|
||||
}
|
||||
@@ -40,39 +50,49 @@ impl<T> From<OutputsByDateRange<T>> for OutputsByDateRange<(OutputFilter, T)> {
|
||||
}
|
||||
|
||||
impl<T> OutputsByDateRange<T> {
|
||||
pub fn as_vec(&mut self) -> [&T; 14] {
|
||||
pub fn as_vec(&mut self) -> [&T; 19] {
|
||||
[
|
||||
&self.start_to_1d,
|
||||
&self._1d_to_1w,
|
||||
&self._1w_to_1m,
|
||||
&self._1m_to_3m,
|
||||
&self._3m_to_6m,
|
||||
&self._1m_to_2m,
|
||||
&self._2m_to_3m,
|
||||
&self._3m_to_4m,
|
||||
&self._4m_to_5m,
|
||||
&self._5m_to_6m,
|
||||
&self._6m_to_1y,
|
||||
&self._1y_to_2y,
|
||||
&self._2y_to_3y,
|
||||
&self._3y_to_4y,
|
||||
&self._4y_to_5y,
|
||||
&self._5y_to_7y,
|
||||
&self._7y_to_10y,
|
||||
&self._5y_to_6y,
|
||||
&self._6y_to_7y,
|
||||
&self._7y_to_8y,
|
||||
&self._8y_to_10y,
|
||||
&self._10y_to_15y,
|
||||
&self._15y_to_end,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn as_mut_vec(&mut self) -> [&mut T; 14] {
|
||||
pub fn as_mut_vec(&mut self) -> [&mut T; 19] {
|
||||
[
|
||||
&mut self.start_to_1d,
|
||||
&mut self._1d_to_1w,
|
||||
&mut self._1w_to_1m,
|
||||
&mut self._1m_to_3m,
|
||||
&mut self._3m_to_6m,
|
||||
&mut self._1m_to_2m,
|
||||
&mut self._2m_to_3m,
|
||||
&mut self._3m_to_4m,
|
||||
&mut self._4m_to_5m,
|
||||
&mut self._5m_to_6m,
|
||||
&mut self._6m_to_1y,
|
||||
&mut self._1y_to_2y,
|
||||
&mut self._2y_to_3y,
|
||||
&mut self._3y_to_4y,
|
||||
&mut self._4y_to_5y,
|
||||
&mut self._5y_to_7y,
|
||||
&mut self._7y_to_10y,
|
||||
&mut self._5y_to_6y,
|
||||
&mut self._6y_to_7y,
|
||||
&mut self._7y_to_8y,
|
||||
&mut self._8y_to_10y,
|
||||
&mut self._10y_to_15y,
|
||||
&mut self._15y_to_end,
|
||||
]
|
||||
@@ -80,20 +100,25 @@ impl<T> OutputsByDateRange<T> {
|
||||
}
|
||||
|
||||
impl<T> OutputsByDateRange<(OutputFilter, T)> {
|
||||
pub fn vecs(&self) -> [&T; 14] {
|
||||
pub fn vecs(&self) -> [&T; 19] {
|
||||
[
|
||||
&self.start_to_1d.1,
|
||||
&self._1d_to_1w.1,
|
||||
&self._1w_to_1m.1,
|
||||
&self._1m_to_3m.1,
|
||||
&self._3m_to_6m.1,
|
||||
&self._1m_to_2m.1,
|
||||
&self._2m_to_3m.1,
|
||||
&self._3m_to_4m.1,
|
||||
&self._4m_to_5m.1,
|
||||
&self._5m_to_6m.1,
|
||||
&self._6m_to_1y.1,
|
||||
&self._1y_to_2y.1,
|
||||
&self._2y_to_3y.1,
|
||||
&self._3y_to_4y.1,
|
||||
&self._4y_to_5y.1,
|
||||
&self._5y_to_7y.1,
|
||||
&self._7y_to_10y.1,
|
||||
&self._5y_to_6y.1,
|
||||
&self._6y_to_7y.1,
|
||||
&self._7y_to_8y.1,
|
||||
&self._8y_to_10y.1,
|
||||
&self._10y_to_15y.1,
|
||||
&self._15y_to_end.1,
|
||||
]
|
||||
|
||||
@@ -408,20 +408,23 @@ where
|
||||
T: From<T4>,
|
||||
{
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.inner.version() + divided.version() + divider.version(),
|
||||
Version::ONE + self.inner.version() + divided.version() + divider.version(),
|
||||
)?;
|
||||
|
||||
let index = max_from.min(I::from(self.len()));
|
||||
let multiplier = if as_percentage { 100 } else { 1 };
|
||||
let subtract = if as_difference { multiplier } else { 0 };
|
||||
|
||||
let mut divider_iter = divider.iter();
|
||||
divided.iter_at(index).try_for_each(|(i, divided)| {
|
||||
let divided = divided.into_inner();
|
||||
let divider = divider_iter.unwrap_get_inner(i);
|
||||
let v = (divided / divider * multiplier)
|
||||
.checked_sub(subtract)
|
||||
.unwrap();
|
||||
let mut v = divided / divider;
|
||||
if as_percentage {
|
||||
v = v * multiplier;
|
||||
}
|
||||
if as_difference {
|
||||
v = v.checked_sub(multiplier).unwrap();
|
||||
}
|
||||
self.forced_push_at(i, T::from(v), exit)
|
||||
})?;
|
||||
|
||||
|
||||
@@ -441,14 +441,14 @@
|
||||
h1,
|
||||
h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: var(--font-size-xl);
|
||||
line-height: var(--line-height-xl);
|
||||
font-weight: 350;
|
||||
font-size: var(--font-size-lg);
|
||||
line-height: var(--line-height-lg);
|
||||
font-weight: 375;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: var(--font-size-xl);
|
||||
line-height: var(--line-height-xl);
|
||||
font-size: var(--font-size-lg);
|
||||
line-height: var(--line-height-lg);
|
||||
}
|
||||
|
||||
h4 {
|
||||
@@ -978,6 +978,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
.chart > legend,
|
||||
#charts > fieldset {
|
||||
text-transform: lowercase;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
margin: -0.75rem var(--negative-main-padding);
|
||||
padding: 0.75rem var(--main-padding);
|
||||
overflow-x: auto;
|
||||
min-width: 0;
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: var(--line-height-sm);
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.chart {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -987,19 +1003,6 @@
|
||||
margin-bottom: 1rem;
|
||||
|
||||
> legend {
|
||||
text-transform: lowercase;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
margin: -0.5rem var(--negative-main-padding);
|
||||
padding: 1rem var(--main-padding);
|
||||
overflow-x: auto;
|
||||
min-width: 0;
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: var(--line-height-sm);
|
||||
scrollbar-width: thin;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
@@ -1052,6 +1055,8 @@
|
||||
height: 100%;
|
||||
margin-right: var(--negative-main-padding);
|
||||
margin-left: var(--negative-main-padding);
|
||||
margin-top: 0.25rem;
|
||||
margin-bottom: 0.25rem;
|
||||
|
||||
fieldset {
|
||||
padding: 0.5rem;
|
||||
|
||||
@@ -503,8 +503,6 @@ export default import("./v5.0.6-treeshaked/script.js").then((lc) => {
|
||||
|
||||
const paneIndex = _paneIndex ?? 0;
|
||||
|
||||
console.log("OPTIONS", options);
|
||||
|
||||
const series = ichart.addSeries(
|
||||
/** @type {SeriesDefinition<'Baseline'>} */ (lc.BaselineSeries),
|
||||
{
|
||||
|
||||
@@ -238,8 +238,10 @@ export function init({
|
||||
paneIndex,
|
||||
options: {
|
||||
...blueprint.options,
|
||||
topLineColor: blueprint.colors?.[0](),
|
||||
bottomLineColor: blueprint.colors?.[1](),
|
||||
topLineColor:
|
||||
blueprint.color?.() ?? blueprint.colors?.[0](),
|
||||
bottomLineColor:
|
||||
blueprint.color?.() ?? blueprint.colors?.[1](),
|
||||
},
|
||||
});
|
||||
break;
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
* @typedef {"" |
|
||||
* "BTC" |
|
||||
* "Cents" |
|
||||
* "Coinblocks" |
|
||||
* "coinblocks" |
|
||||
* "coindays" |
|
||||
* "satblocks" |
|
||||
* "satdays" |
|
||||
* "Count" |
|
||||
* "Date" |
|
||||
* "Difficulty" |
|
||||
@@ -874,6 +877,22 @@ function createUtils() {
|
||||
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
|
||||
unit = "Timestamp";
|
||||
}
|
||||
if ((!unit || thoroughUnitCheck) && id.includes("coinblocks")) {
|
||||
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
|
||||
unit = "coinblocks";
|
||||
}
|
||||
if ((!unit || thoroughUnitCheck) && id.includes("coindays")) {
|
||||
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
|
||||
unit = "coindays";
|
||||
}
|
||||
if ((!unit || thoroughUnitCheck) && id.includes("satblocks")) {
|
||||
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
|
||||
unit = "satblocks";
|
||||
}
|
||||
if ((!unit || thoroughUnitCheck) && id.includes("satdays")) {
|
||||
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
|
||||
unit = "satdays";
|
||||
}
|
||||
if ((!unit || thoroughUnitCheck) && id.endsWith("height")) {
|
||||
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
|
||||
unit = "Height";
|
||||
|
||||
@@ -465,15 +465,33 @@ function createPartialOptions(colors) {
|
||||
color: colors.orange,
|
||||
},
|
||||
{
|
||||
key: "from-1m-to-3m",
|
||||
name: "1m..3m",
|
||||
title: "From 1 Month ago to 3 Months ago",
|
||||
key: "from-1m-to-2m",
|
||||
name: "1m..2m",
|
||||
title: "From 1 Month ago to 2 Months ago",
|
||||
color: colors.yellow,
|
||||
},
|
||||
{
|
||||
key: "from-3m-to-6m",
|
||||
name: "3m..6m",
|
||||
title: "From 3 Month ago to 6 Months ago",
|
||||
key: "from-2m-to-3m",
|
||||
name: "2m..3m",
|
||||
title: "From 2 Month ago to 3 Months ago",
|
||||
color: colors.yellow,
|
||||
},
|
||||
{
|
||||
key: "from-3m-to-4m",
|
||||
name: "3m..4m",
|
||||
title: "From 3 Month ago to 4 Months ago",
|
||||
color: colors.lime,
|
||||
},
|
||||
{
|
||||
key: "from-4m-to-5m",
|
||||
name: "4m..5m",
|
||||
title: "From 4 Month ago to 5 Months ago",
|
||||
color: colors.lime,
|
||||
},
|
||||
{
|
||||
key: "from-5m-to-6m",
|
||||
name: "5m..6m",
|
||||
title: "From 5 Month ago to 6 Months ago",
|
||||
color: colors.lime,
|
||||
},
|
||||
{
|
||||
@@ -507,15 +525,27 @@ function createPartialOptions(colors) {
|
||||
color: colors.violet,
|
||||
},
|
||||
{
|
||||
key: "from-5y-to-7y",
|
||||
name: "5y..7y",
|
||||
title: "From 5 Years ago to 7 Years ago",
|
||||
key: "from-5y-to-6y",
|
||||
name: "5y..6y",
|
||||
title: "From 5 Years ago to 6 Years ago",
|
||||
color: colors.purple,
|
||||
},
|
||||
{
|
||||
key: "from-7y-to-10y",
|
||||
name: "7y..10y",
|
||||
title: "From 7 Years ago to 10 Years ago",
|
||||
key: "from-6y-to-7y",
|
||||
name: "6y..7y",
|
||||
title: "From 6 Years ago to 7 Years ago",
|
||||
color: colors.purple,
|
||||
},
|
||||
{
|
||||
key: "from-7y-to-8y",
|
||||
name: "7y..8y",
|
||||
title: "From 7 Years ago to 8 Years ago",
|
||||
color: colors.fuchsia,
|
||||
},
|
||||
{
|
||||
key: "from-8y-to-10y",
|
||||
name: "8y..10y",
|
||||
title: "From 8 Years ago to 10 Years ago",
|
||||
color: colors.fuchsia,
|
||||
},
|
||||
{
|
||||
@@ -1489,34 +1519,78 @@ function createPartialOptions(colors) {
|
||||
}),
|
||||
]),
|
||||
},
|
||||
{
|
||||
name: "sopr",
|
||||
title: `${args.title} Spent Output Profit Ratio`,
|
||||
bottom: list.flatMap(({ color, name, key }) => [
|
||||
/** @satisfies {FetchedBaselineSeriesBlueprint} */ ({
|
||||
type: "Baseline",
|
||||
key: `${fixKey(key)}spent-output-profit-ratio`,
|
||||
title: useGroupName ? name : "sopr",
|
||||
color: useGroupName ? color : undefined,
|
||||
options: {
|
||||
createPriceLine: {
|
||||
value: 1,
|
||||
},
|
||||
...(!("list" in args)
|
||||
? [
|
||||
{
|
||||
name: "sopr",
|
||||
title: `${args.title} Spent Output Profit Ratio`,
|
||||
bottom: list.flatMap(({ color, name, key }) => [
|
||||
/** @satisfies {FetchedBaselineSeriesBlueprint} */ ({
|
||||
type: "Baseline",
|
||||
key: `${fixKey(key)}spent-output-profit-ratio`,
|
||||
title: useGroupName ? name : "sopr",
|
||||
color: useGroupName ? color : undefined,
|
||||
options: {
|
||||
createPriceLine: {
|
||||
value: 1,
|
||||
},
|
||||
},
|
||||
}),
|
||||
/** @satisfies {FetchedBaselineSeriesBlueprint} */ ({
|
||||
type: "Baseline",
|
||||
key: `${fixKey(key)}adjusted-spent-output-profit-ratio`,
|
||||
title: useGroupName ? name : "asopr",
|
||||
color: useGroupName ? color : undefined,
|
||||
options: {
|
||||
createPriceLine: {
|
||||
value: 1,
|
||||
},
|
||||
},
|
||||
}),
|
||||
]),
|
||||
},
|
||||
}),
|
||||
/** @satisfies {FetchedBaselineSeriesBlueprint} */ ({
|
||||
type: "Baseline",
|
||||
key: `${fixKey(key)}adjusted-spent-output-profit-ratio`,
|
||||
title: useGroupName ? name : "asopr",
|
||||
color: useGroupName ? color : undefined,
|
||||
options: {
|
||||
createPriceLine: {
|
||||
value: 1,
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
name: "sopr",
|
||||
tree: [
|
||||
{
|
||||
name: "Normal",
|
||||
title: `${args.title} Spent Output Profit Ratio`,
|
||||
bottom: list.flatMap(({ color, name, key }) => [
|
||||
/** @satisfies {FetchedBaselineSeriesBlueprint} */ ({
|
||||
type: "Baseline",
|
||||
key: `${fixKey(key)}spent-output-profit-ratio`,
|
||||
title: useGroupName ? name : "sopr",
|
||||
color: useGroupName ? color : undefined,
|
||||
options: {
|
||||
createPriceLine: {
|
||||
value: 1,
|
||||
},
|
||||
},
|
||||
}),
|
||||
]),
|
||||
},
|
||||
{
|
||||
name: "Adjusted",
|
||||
title: `${args.title} Adjusted Spent Output Profit Ratio`,
|
||||
bottom: list.flatMap(({ color, name, key }) => [
|
||||
/** @satisfies {FetchedBaselineSeriesBlueprint} */ ({
|
||||
type: "Baseline",
|
||||
key: `${fixKey(key)}adjusted-spent-output-profit-ratio`,
|
||||
title: useGroupName ? name : "asopr",
|
||||
color: useGroupName ? color : undefined,
|
||||
options: {
|
||||
createPriceLine: {
|
||||
value: 1,
|
||||
},
|
||||
},
|
||||
}),
|
||||
]),
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
]),
|
||||
},
|
||||
]),
|
||||
{
|
||||
name: "Sell Side Risk Ratio",
|
||||
title: `${args.title} Sell Side Risk Ratio`,
|
||||
@@ -1634,7 +1708,7 @@ function createPartialOptions(colors) {
|
||||
{
|
||||
name: "Average",
|
||||
title: `${args.title} Average Price Paid`,
|
||||
bottom: list.flatMap(({ color, name, key: _key }) => {
|
||||
top: list.flatMap(({ color, name, key: _key }) => {
|
||||
const key = fixKey(_key);
|
||||
return /** @type {const} */ ([
|
||||
createBaseSeries({
|
||||
@@ -1648,7 +1722,7 @@ function createPartialOptions(colors) {
|
||||
{
|
||||
name: "Min",
|
||||
title: `${args.title} Min Price Paid`,
|
||||
bottom: list.flatMap(({ color, name, key: _key }) => {
|
||||
top: list.flatMap(({ color, name, key: _key }) => {
|
||||
const key = fixKey(_key);
|
||||
return /** @type {const} */ ([
|
||||
createBaseSeries({
|
||||
@@ -1662,7 +1736,7 @@ function createPartialOptions(colors) {
|
||||
{
|
||||
name: "Max",
|
||||
title: `${args.title} Max Price Paid`,
|
||||
bottom: list.flatMap(({ color, name, key: _key }) => {
|
||||
top: list.flatMap(({ color, name, key: _key }) => {
|
||||
const key = fixKey(_key);
|
||||
return /** @type {const} */ ([
|
||||
createBaseSeries({
|
||||
@@ -1701,6 +1775,35 @@ function createPartialOptions(colors) {
|
||||
],
|
||||
},
|
||||
]),
|
||||
{
|
||||
name: "Coins Destroyed",
|
||||
title: `${args.title} Coins Destroyed`,
|
||||
bottom: list.flatMap(({ color, name, key: _key }) => {
|
||||
const key = fixKey(_key);
|
||||
return /** @type {const} */ ([
|
||||
createBaseSeries({
|
||||
key: `${key}coinblocks-destroyed`,
|
||||
name: useGroupName ? name : "destroyed",
|
||||
color,
|
||||
}),
|
||||
createBaseSeries({
|
||||
key: `${key}coindays-destroyed`,
|
||||
name: useGroupName ? name : "destroyed",
|
||||
color,
|
||||
}),
|
||||
createBaseSeries({
|
||||
key: `${key}coinblocks-destroyed-sum`,
|
||||
name: useGroupName ? name : "destroyed",
|
||||
color,
|
||||
}),
|
||||
createBaseSeries({
|
||||
key: `${key}coindays-destroyed-sum`,
|
||||
name: useGroupName ? name : "destroyed",
|
||||
color,
|
||||
}),
|
||||
]);
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
@@ -2722,14 +2825,14 @@ function createPartialOptions(colors) {
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Services",
|
||||
name: "Hosting",
|
||||
tree: [
|
||||
{
|
||||
name: "Self-host",
|
||||
name: "Self",
|
||||
url: () => "https://crates.io/crates/brk_cli",
|
||||
},
|
||||
{
|
||||
name: "Hosting as a service",
|
||||
name: "As a service",
|
||||
url: () =>
|
||||
"https://github.com/bitcoinresearchkit/brk?tab=readme-ov-file#hosting-as-a-service",
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@
|
||||
white-space: nowrap;
|
||||
overflow-x: auto;
|
||||
padding-bottom: 1rem;
|
||||
margin-bottom: -1rem;
|
||||
margin-bottom: -2rem;
|
||||
padding-left: var(--main-padding);
|
||||
margin-left: var(--negative-main-padding);
|
||||
padding-right: var(--main-padding);
|
||||
@@ -28,7 +28,11 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
> * {
|
||||
.lightweight-chart {
|
||||
z-index: 30;
|
||||
}
|
||||
|
||||
> * {
|
||||
/* z-index: 30; */
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user