mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot part 16
This commit is contained in:
@@ -67,8 +67,8 @@ pub(crate) fn process_blocks(
|
||||
let height_to_first_txout_index = &indexer.vecs.outputs.first_txout_index;
|
||||
let height_to_first_txin_index = &indexer.vecs.inputs.first_txin_index;
|
||||
let height_to_tx_count = &transactions.count.total.block;
|
||||
let height_to_output_count = &outputs.count.total.sum.height;
|
||||
let height_to_input_count = &inputs.count.sum.height;
|
||||
let height_to_output_count = &outputs.count.total.sum;
|
||||
let height_to_input_count = &inputs.count.sum;
|
||||
let tx_index_to_output_count = &indexes.tx_index.output_count;
|
||||
let tx_index_to_input_count = &indexes.tx_index.input_count;
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{BasisPointsSigned32, Bitcoin, Cents, CentsSigned, Dollars, Height, Indexes, StoredF64, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::{
|
||||
AnyStoredVec, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode, WritableVec,
|
||||
AnyStoredVec, Exit, LazyVecFrom1, ReadableCloneableVec, ReadableVec, Rw, StorageMode,
|
||||
WritableVec,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -22,7 +23,7 @@ use super::RealizedMinimal;
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct NegRealizedLoss {
|
||||
#[traversable(flatten)]
|
||||
pub base: LazyPerBlock<Dollars, Cents>,
|
||||
pub base: LazyVecFrom1<Height, Dollars, Height, Cents>,
|
||||
pub sum: Windows<LazyPerBlock<Dollars, Cents>>,
|
||||
}
|
||||
|
||||
@@ -51,11 +52,10 @@ impl RealizedCore {
|
||||
|
||||
let minimal = RealizedMinimal::forced_import(cfg)?;
|
||||
|
||||
let neg_loss_base = LazyPerBlock::from_height_source::<NegCentsUnsignedToDollars>(
|
||||
let neg_loss_base = LazyVecFrom1::transformed::<NegCentsUnsignedToDollars>(
|
||||
&cfg.name("realized_loss_neg"),
|
||||
cfg.version + Version::ONE,
|
||||
minimal.loss.block.cents.read_only_boxed_clone(),
|
||||
cfg.indexes,
|
||||
);
|
||||
|
||||
let neg_loss_sum = minimal.loss.sum.0.map_with_suffix(|suffix, slot| {
|
||||
|
||||
@@ -22,7 +22,7 @@ impl Vecs {
|
||||
.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
|
||||
starting_indexes.height,
|
||||
&mining.rewards.subsidy.block.usd,
|
||||
&mining.rewards.subsidy_sma_1y.usd.height,
|
||||
&mining.rewards.subsidy.average._1y.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Version};
|
||||
use vecdb::{Database, Exit, Rw, StorageMode};
|
||||
use brk_types::{Height, Sats, Version};
|
||||
use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
@@ -57,4 +57,15 @@ impl AmountPerBlockCumulative {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn compute_with(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
prices: &prices::Vecs,
|
||||
exit: &Exit,
|
||||
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
|
||||
) -> Result<()> {
|
||||
compute_sats(&mut self.block.sats)?;
|
||||
self.compute(prices, max_from, exit)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ use brk_traversable::Traversable;
|
||||
use brk_types::Height;
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{
|
||||
AnyStoredVec, AnyVec, Database, Exit, ReadableVec, Rw, StorageMode, VecIndex, VecValue,
|
||||
Version, WritableVec,
|
||||
AnyStoredVec, AnyVec, Database, EagerVec, Exit, ImportableVec, PcoVec, ReadableVec, Rw,
|
||||
StorageMode, VecIndex, VecValue, Version, WritableVec,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -17,7 +17,7 @@ pub struct PerBlockAggregated<T, M: StorageMode = Rw>
|
||||
where
|
||||
T: NumericValue + JsonSchema,
|
||||
{
|
||||
pub sum: PerBlock<T, M>,
|
||||
pub sum: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
||||
pub cumulative: PerBlock<T, M>,
|
||||
pub rolling: RollingComplete<T, M>,
|
||||
}
|
||||
@@ -33,7 +33,7 @@ where
|
||||
indexes: &indexes::Vecs,
|
||||
cached_starts: &CachedWindowStarts,
|
||||
) -> Result<Self> {
|
||||
let sum = PerBlock::forced_import(db, &format!("{name}_sum"), version, indexes)?;
|
||||
let sum = EagerVec::forced_import(db, &format!("{name}_sum"), version)?;
|
||||
let cumulative =
|
||||
PerBlock::forced_import(db, &format!("{name}_cumulative"), version, indexes)?;
|
||||
let rolling = RollingComplete::forced_import(
|
||||
@@ -73,9 +73,8 @@ where
|
||||
let mut index = max_from;
|
||||
index = {
|
||||
self.sum
|
||||
.height
|
||||
.validate_computed_version_or_reset(combined_version)?;
|
||||
index.min(Height::from(self.sum.height.len()))
|
||||
index.min(Height::from(self.sum.len()))
|
||||
};
|
||||
index = {
|
||||
self.cumulative
|
||||
@@ -86,7 +85,7 @@ where
|
||||
|
||||
let start = index.to_usize();
|
||||
|
||||
self.sum.height.truncate_if_needed_at(start)?;
|
||||
self.sum.truncate_if_needed_at(start)?;
|
||||
self.cumulative.height.truncate_if_needed_at(start)?;
|
||||
|
||||
let mut cumulative_val = index.decremented().map_or(T::from(0_usize), |idx| {
|
||||
@@ -117,7 +116,7 @@ where
|
||||
|acc, val| acc + val,
|
||||
);
|
||||
|
||||
self.sum.height.push(sum_val);
|
||||
self.sum.push(sum_val);
|
||||
cumulative_val += sum_val;
|
||||
self.cumulative.height.push(cumulative_val);
|
||||
|
||||
@@ -125,12 +124,11 @@ where
|
||||
})?;
|
||||
|
||||
let _lock = exit.lock();
|
||||
self.sum.height.write()?;
|
||||
self.sum.write()?;
|
||||
self.cumulative.height.write()?;
|
||||
drop(_lock);
|
||||
|
||||
self.rolling
|
||||
.compute(max_from, windows, &self.sum.height, exit)?;
|
||||
self.rolling.compute(max_from, windows, &self.sum, exit)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,10 +58,9 @@ impl Vecs {
|
||||
r3?;
|
||||
r4?;
|
||||
|
||||
// Phase 3: Depends on returns, range, moving_average
|
||||
// Phase 3: Depends on returns, moving_average
|
||||
self.technical.compute(
|
||||
&self.returns,
|
||||
&self.range,
|
||||
prices,
|
||||
blocks,
|
||||
&self.moving_average,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::{BasisPoints16, Dollars, Indexes};
|
||||
use brk_types::{Dollars, Indexes};
|
||||
use vecdb::Exit;
|
||||
|
||||
use super::{
|
||||
super::{moving_average, range, returns},
|
||||
super::{moving_average, returns},
|
||||
Vecs, macd, rsi,
|
||||
};
|
||||
use crate::{blocks, internal::{RatioDollarsBp32, WindowsTo1m}, prices};
|
||||
@@ -13,37 +13,12 @@ impl Vecs {
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
returns: &returns::Vecs,
|
||||
range: &range::Vecs,
|
||||
prices: &prices::Vecs,
|
||||
blocks: &blocks::Vecs,
|
||||
moving_average: &moving_average::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.stoch_k.bps.height.compute_transform3(
|
||||
starting_indexes.height,
|
||||
&prices.spot.usd.height,
|
||||
&range.min._2w.usd.height,
|
||||
&range.max._2w.usd.height,
|
||||
|(h, close, low, high, ..)| {
|
||||
let range = *high - *low;
|
||||
let stoch = if range == 0.0 {
|
||||
BasisPoints16::ZERO
|
||||
} else {
|
||||
BasisPoints16::from((*close - *low) / range)
|
||||
};
|
||||
(h, stoch)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.stoch_d.bps.height.compute_rolling_average(
|
||||
starting_indexes.height,
|
||||
&blocks.lookback._3d,
|
||||
&self.stoch_k.bps.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let daily_returns = &returns.periods._24h.ratio.height;
|
||||
for (rsi_chain, &m) in self.rsi.as_mut_array().into_iter().zip(&WindowsTo1m::<()>::DAYS) {
|
||||
rsi::compute(
|
||||
|
||||
@@ -110,15 +110,10 @@ impl Vecs {
|
||||
WindowsTo1m::try_from_fn(|tf| RsiChain::forced_import(db, tf, v + Version::TWO, indexes))?;
|
||||
let macd = WindowsTo1m::try_from_fn(|tf| MacdChain::forced_import(db, tf, v, indexes))?;
|
||||
|
||||
let stoch_k = PercentPerBlock::forced_import(db, "stoch_k", v, indexes)?;
|
||||
let stoch_d = PercentPerBlock::forced_import(db, "stoch_d", v, indexes)?;
|
||||
|
||||
let pi_cycle = RatioPerBlock::forced_import_raw(db, "pi_cycle", v, indexes)?;
|
||||
|
||||
Ok(Self {
|
||||
rsi,
|
||||
stoch_k,
|
||||
stoch_d,
|
||||
pi_cycle,
|
||||
macd,
|
||||
})
|
||||
|
||||
@@ -6,13 +6,20 @@ use crate::internal::{PerBlock, PercentPerBlock, RatioPerBlock, WindowsTo1m};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct RsiChain<M: StorageMode = Rw> {
|
||||
#[traversable(hidden)]
|
||||
pub gains: PerBlock<StoredF32, M>,
|
||||
#[traversable(hidden)]
|
||||
pub losses: PerBlock<StoredF32, M>,
|
||||
#[traversable(hidden)]
|
||||
pub average_gain: PerBlock<StoredF32, M>,
|
||||
#[traversable(hidden)]
|
||||
pub average_loss: PerBlock<StoredF32, M>,
|
||||
pub rsi: PercentPerBlock<BasisPoints16, M>,
|
||||
#[traversable(hidden)]
|
||||
pub rsi_min: PercentPerBlock<BasisPoints16, M>,
|
||||
#[traversable(hidden)]
|
||||
pub rsi_max: PercentPerBlock<BasisPoints16, M>,
|
||||
#[traversable(hidden)]
|
||||
pub stoch_rsi: PercentPerBlock<BasisPoints16, M>,
|
||||
pub stoch_rsi_k: PercentPerBlock<BasisPoints16, M>,
|
||||
pub stoch_rsi_d: PercentPerBlock<BasisPoints16, M>,
|
||||
@@ -31,9 +38,6 @@ pub struct MacdChain<M: StorageMode = Rw> {
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub rsi: WindowsTo1m<RsiChain<M>>,
|
||||
|
||||
pub stoch_k: PercentPerBlock<BasisPoints16, M>,
|
||||
pub stoch_d: PercentPerBlock<BasisPoints16, M>,
|
||||
|
||||
pub pi_cycle: RatioPerBlock<BasisPoints32, M>,
|
||||
|
||||
pub macd: WindowsTo1m<MacdChain<M>>,
|
||||
|
||||
@@ -133,13 +133,6 @@ impl Vecs {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.subsidy_sma_1y.cents.height.compute_rolling_average(
|
||||
starting_indexes.height,
|
||||
&lookback._1y,
|
||||
&self.subsidy.block.cents,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.fee_to_subsidy_ratio
|
||||
.compute_binary::<Dollars, Dollars, RatioDollarsBp32, _, _>(
|
||||
starting_indexes.height,
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
AmountPerBlockCumulative, AmountPerBlockCumulativeRolling, AmountPerBlockFull,
|
||||
CachedWindowStarts, FiatPerBlock, LazyPercentRollingWindows, OneMinusBp16,
|
||||
CachedWindowStarts, LazyPercentRollingWindows, OneMinusBp16,
|
||||
PercentPerBlock, PercentRollingWindows, RatioRollingWindows,
|
||||
},
|
||||
};
|
||||
@@ -55,7 +55,6 @@ impl Vecs {
|
||||
indexes,
|
||||
)?,
|
||||
subsidy_dominance_rolling,
|
||||
subsidy_sma_1y: FiatPerBlock::forced_import(db, "subsidy_sma_1y", version, indexes)?,
|
||||
fee_to_subsidy_ratio: RatioRollingWindows::forced_import(
|
||||
db,
|
||||
"fee_to_subsidy_ratio",
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{BasisPoints16, BasisPoints32, Cents};
|
||||
use brk_types::{BasisPoints16, BasisPoints32};
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::{
|
||||
AmountPerBlockCumulative, AmountPerBlockCumulativeRolling, AmountPerBlockFull,
|
||||
FiatPerBlock, LazyPercentRollingWindows, PercentPerBlock, PercentRollingWindows,
|
||||
RatioRollingWindows,
|
||||
LazyPercentRollingWindows, PercentPerBlock, PercentRollingWindows, RatioRollingWindows,
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
@@ -22,8 +21,6 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub subsidy_dominance: PercentPerBlock<BasisPoints16, M>,
|
||||
#[traversable(wrap = "subsidy", rename = "dominance")]
|
||||
pub subsidy_dominance_rolling: LazyPercentRollingWindows<BasisPoints16>,
|
||||
#[traversable(wrap = "subsidy", rename = "sma_1y")]
|
||||
pub subsidy_sma_1y: FiatPerBlock<Cents, M>,
|
||||
#[traversable(wrap = "fees", rename = "to_subsidy_ratio")]
|
||||
pub fee_to_subsidy_ratio: RatioRollingWindows<BasisPoints32, M>,
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ impl Vecs {
|
||||
let version = parent_version;
|
||||
|
||||
let count = CountVecs::forced_import(&db, version, indexes, cached_starts)?;
|
||||
let value = ValueVecs::forced_import(&db, version, indexes, cached_starts)?;
|
||||
let value = ValueVecs::forced_import(&db, version, indexes)?;
|
||||
|
||||
let this = Self { db, count, value };
|
||||
finalize_db(&this.db, &this)?;
|
||||
|
||||
@@ -14,7 +14,7 @@ impl Vecs {
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.op_return.compute(
|
||||
self.op_return.compute_with(
|
||||
starting_indexes.height,
|
||||
prices,
|
||||
exit,
|
||||
|
||||
@@ -3,22 +3,20 @@ use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{indexes, internal::{AmountPerBlockCumulativeRolling, CachedWindowStarts}};
|
||||
use crate::{indexes, internal::AmountPerBlockCumulative};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
cached_starts: &CachedWindowStarts,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
op_return: AmountPerBlockCumulativeRolling::forced_import(
|
||||
op_return: AmountPerBlockCumulative::forced_import(
|
||||
db,
|
||||
"op_return_value",
|
||||
version,
|
||||
indexes,
|
||||
cached_starts,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use brk_traversable::Traversable;
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::AmountPerBlockCumulativeRolling;
|
||||
use crate::internal::AmountPerBlockCumulative;
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub op_return: AmountPerBlockCumulativeRolling<M>,
|
||||
pub op_return: AmountPerBlockCumulative<M>,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::{Height, Indexes, Sats};
|
||||
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableVec, VecIndex, WritableVec};
|
||||
use brk_types::{Indexes, Sats};
|
||||
use vecdb::{Exit, VecIndex};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{mining, prices, scripts};
|
||||
@@ -14,46 +14,21 @@ impl Vecs {
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let op_return_height = &scripts.value.op_return.block.sats;
|
||||
let unclaimed_height = &mining.rewards.unclaimed.block.sats;
|
||||
|
||||
self.total.compute(
|
||||
self.total.compute_with(
|
||||
starting_indexes.height,
|
||||
prices,
|
||||
exit,
|
||||
|height_vec| {
|
||||
let unspendable_dep_version =
|
||||
op_return_height.version() + unclaimed_height.version();
|
||||
height_vec.validate_computed_version_or_reset(unspendable_dep_version)?;
|
||||
|
||||
let op_return_target = op_return_height.len();
|
||||
if op_return_target > 0 {
|
||||
let target_height = Height::from(op_return_target - 1);
|
||||
let current_len = height_vec.len();
|
||||
let starting_height =
|
||||
Height::from(current_len.min(starting_indexes.height.to_usize()));
|
||||
|
||||
if starting_height <= target_height {
|
||||
let start = starting_height.to_usize();
|
||||
let end = target_height.to_usize() + 1;
|
||||
let unclaimed_data = unclaimed_height.collect_range_at(start, end);
|
||||
height_vec.truncate_if_needed(starting_height)?;
|
||||
op_return_height.fold_range_at(start, end, start, |idx, op_return| {
|
||||
let unclaimed = unclaimed_data[idx - start];
|
||||
let genesis = if idx == 0 {
|
||||
Sats::FIFTY_BTC
|
||||
} else {
|
||||
Sats::ZERO
|
||||
};
|
||||
let unspendable = genesis + op_return + unclaimed;
|
||||
height_vec.push(unspendable);
|
||||
idx + 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
height_vec.write()?;
|
||||
Ok(())
|
||||
|sats| {
|
||||
Ok(sats.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&scripts.value.op_return.block.sats,
|
||||
&mining.rewards.unclaimed.block.sats,
|
||||
|(h, op_return, unclaimed, ..)| {
|
||||
let genesis = if h.to_usize() == 0 { Sats::FIFTY_BTC } else { Sats::ZERO };
|
||||
(h, genesis + op_return + unclaimed)
|
||||
},
|
||||
exit,
|
||||
)?)
|
||||
},
|
||||
)?;
|
||||
|
||||
|
||||
@@ -3,22 +3,20 @@ use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{indexes, internal::{AmountPerBlockCumulativeRolling, CachedWindowStarts}};
|
||||
use crate::{indexes, internal::AmountPerBlockCumulative};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
cached_starts: &CachedWindowStarts,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
total: AmountPerBlockCumulativeRolling::forced_import(
|
||||
total: AmountPerBlockCumulative::forced_import(
|
||||
db,
|
||||
"unspendable_supply",
|
||||
version,
|
||||
indexes,
|
||||
cached_starts,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use brk_traversable::Traversable;
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::AmountPerBlockCumulativeRolling;
|
||||
use crate::internal::AmountPerBlockCumulative;
|
||||
|
||||
#[derive(Traversable)]
|
||||
#[traversable(transparent)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub total: AmountPerBlockCumulativeRolling<M>,
|
||||
pub total: AmountPerBlockCumulative<M>,
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ impl Vecs {
|
||||
let circulating =
|
||||
LazyAmountPerBlock::identity("circulating_supply", &supply_metrics.total, version);
|
||||
|
||||
let burned = burned::Vecs::forced_import(&db, version, indexes, cached_starts)?;
|
||||
let burned = burned::Vecs::forced_import(&db, version, indexes)?;
|
||||
|
||||
// Inflation rate
|
||||
let inflation_rate = PercentPerBlock::forced_import(
|
||||
|
||||
Reference in New Issue
Block a user