global: snapshot

This commit is contained in:
nym21
2026-01-10 18:43:18 +01:00
parent 3bc0615000
commit 6f45ec13f3
311 changed files with 6916 additions and 7664 deletions

View File

@@ -8,7 +8,7 @@ use vecdb::{
AnyStoredVec, AnyVec, Database, EagerVec, Exit, GenericStoredVec, PcoVec, TypedVecIterator,
};
use crate::{ComputeIndexes, indexes, internal::ComputedBlockLast};
use crate::{ComputeIndexes, indexes, internal::ComputedFromHeightLast};
/// Address count per address type (runtime state).
#[derive(Debug, Default, Deref, DerefMut)]
@@ -78,11 +78,11 @@ impl From<(&AddressTypeToAddrCountVecs, Height)> for AddressTypeToAddressCount {
/// Address count per address type, with height + derived indexes.
#[derive(Clone, Deref, DerefMut, Traversable)]
pub struct AddressTypeToAddrCountVecs(ByAddressType<ComputedBlockLast<StoredU64>>);
pub struct AddressTypeToAddrCountVecs(ByAddressType<ComputedFromHeightLast<StoredU64>>);
impl From<ByAddressType<ComputedBlockLast<StoredU64>>> for AddressTypeToAddrCountVecs {
impl From<ByAddressType<ComputedFromHeightLast<StoredU64>>> for AddressTypeToAddrCountVecs {
#[inline]
fn from(value: ByAddressType<ComputedBlockLast<StoredU64>>) -> Self {
fn from(value: ByAddressType<ComputedFromHeightLast<StoredU64>>) -> Self {
Self(value)
}
}
@@ -95,8 +95,8 @@ impl AddressTypeToAddrCountVecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self::from(
ByAddressType::<ComputedBlockLast<StoredU64>>::new_with_name(|type_name| {
ComputedBlockLast::forced_import(
ByAddressType::<ComputedFromHeightLast<StoredU64>>::new_with_name(|type_name| {
ComputedFromHeightLast::forced_import(
db,
&format!("{type_name}_{name}"),
version,
@@ -224,7 +224,7 @@ impl AddressTypeToAddrCountVecs {
#[derive(Clone, Traversable)]
pub struct AddrCountVecs {
pub all: ComputedBlockLast<StoredU64>,
pub all: ComputedFromHeightLast<StoredU64>,
#[traversable(flatten)]
pub by_addresstype: AddressTypeToAddrCountVecs,
}
@@ -237,7 +237,7 @@ impl AddrCountVecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
all: ComputedBlockLast::forced_import(db, name, version, indexes)?,
all: ComputedFromHeightLast::forced_import(db, name, version, indexes)?,
by_addresstype: AddressTypeToAddrCountVecs::forced_import(db, name, version, indexes)?,
})
}

View File

@@ -1,3 +1,6 @@
use std::thread;
use brk_cohort::ByAddressType;
use brk_error::{Error, Result};
use brk_traversable::Traversable;
use brk_types::{
@@ -6,10 +9,14 @@ use brk_types::{
TypeIndex, Version,
};
use rayon::prelude::*;
use rustc_hash::FxHashMap;
use vecdb::{
AnyStoredVec, BytesVec, Database, GenericStoredVec, ImportOptions, ImportableVec, Reader, Stamp,
AnyStoredVec, AnyVec, BytesVec, Database, GenericStoredVec, ImportOptions, ImportableVec,
Reader, Stamp,
};
use super::super::AddressTypeToTypeIndexMap;
const SAVED_STAMPED_CHANGES: u16 = 10;
/// Macro to define AnyAddressIndexesVecs and its methods.
@@ -75,6 +82,31 @@ macro_rules! define_any_address_indexes_vecs {
Ok(())
}
/// Get length for a given address type.
pub fn len_of(&self, address_type: OutputType) -> usize {
match address_type {
$(OutputType::$variant => self.$field.len(),)*
_ => unreachable!("Invalid address type: {:?}", address_type),
}
}
/// Update existing entry (must be within bounds).
pub fn update(&mut self, address_type: OutputType, typeindex: TypeIndex, index: AnyAddressIndex) -> Result<()> {
match address_type {
$(OutputType::$variant => self.$field.update(typeindex.into(), index)?,)*
_ => unreachable!("Invalid address type: {:?}", address_type),
}
Ok(())
}
/// Push new entry (must be at exactly len position).
pub fn push(&mut self, address_type: OutputType, index: AnyAddressIndex) {
match address_type {
$(OutputType::$variant => self.$field.push(index),)*
_ => unreachable!("Invalid address type: {:?}", address_type),
}
}
/// Write all address types with stamp.
pub fn write(&mut self, stamp: Stamp, with_changes: bool) -> Result<()> {
$(self.$field.stamped_write_maybe_with_changes(stamp, with_changes)?;)*
@@ -100,3 +132,102 @@ define_any_address_indexes_vecs!(
(p2wpkh, P2WPKH, P2WPKHAddressIndex),
(p2wsh, P2WSH, P2WSHAddressIndex),
);
impl AnyAddressIndexesVecs {
/// Process index updates in parallel by address type.
/// Accepts two maps (e.g. from empty and loaded processing) and merges per-thread.
/// Updates existing entries and pushes new ones (sorted).
/// Returns (update_count, push_count).
pub fn par_batch_update(
&mut self,
updates1: AddressTypeToTypeIndexMap<AnyAddressIndex>,
updates2: AddressTypeToTypeIndexMap<AnyAddressIndex>,
) -> Result<(usize, usize)> {
let ByAddressType {
p2a: u1_p2a,
p2pk33: u1_p2pk33,
p2pk65: u1_p2pk65,
p2pkh: u1_p2pkh,
p2sh: u1_p2sh,
p2tr: u1_p2tr,
p2wpkh: u1_p2wpkh,
p2wsh: u1_p2wsh,
} = updates1.into_inner();
let ByAddressType {
p2a: u2_p2a,
p2pk33: u2_p2pk33,
p2pk65: u2_p2pk65,
p2pkh: u2_p2pkh,
p2sh: u2_p2sh,
p2tr: u2_p2tr,
p2wpkh: u2_p2wpkh,
p2wsh: u2_p2wsh,
} = updates2.into_inner();
let Self {
p2a,
p2pk33,
p2pk65,
p2pkh,
p2sh,
p2tr,
p2wpkh,
p2wsh,
} = self;
thread::scope(|s| {
let h_p2a = s.spawn(|| process_single_type_merged(p2a, u1_p2a, u2_p2a));
let h_p2pk33 = s.spawn(|| process_single_type_merged(p2pk33, u1_p2pk33, u2_p2pk33));
let h_p2pk65 = s.spawn(|| process_single_type_merged(p2pk65, u1_p2pk65, u2_p2pk65));
let h_p2pkh = s.spawn(|| process_single_type_merged(p2pkh, u1_p2pkh, u2_p2pkh));
let h_p2sh = s.spawn(|| process_single_type_merged(p2sh, u1_p2sh, u2_p2sh));
let h_p2tr = s.spawn(|| process_single_type_merged(p2tr, u1_p2tr, u2_p2tr));
let h_p2wpkh = s.spawn(|| process_single_type_merged(p2wpkh, u1_p2wpkh, u2_p2wpkh));
let h_p2wsh = s.spawn(|| process_single_type_merged(p2wsh, u1_p2wsh, u2_p2wsh));
let mut total_updates = 0usize;
let mut total_pushes = 0usize;
for h in [
h_p2a, h_p2pk33, h_p2pk65, h_p2pkh, h_p2sh, h_p2tr, h_p2wpkh, h_p2wsh,
] {
let (updates, pushes) = h.join().unwrap()?;
total_updates += updates;
total_pushes += pushes;
}
Ok((total_updates, total_pushes))
})
}
}
/// Process updates for a single address type's BytesVec, merging two maps.
fn process_single_type_merged<I: vecdb::VecIndex>(
vec: &mut BytesVec<I, AnyAddressIndex>,
map1: FxHashMap<TypeIndex, AnyAddressIndex>,
map2: FxHashMap<TypeIndex, AnyAddressIndex>,
) -> Result<(usize, usize)> {
let current_len = vec.len();
let mut pushes = Vec::with_capacity(map1.len() + map2.len());
let mut update_count = 0usize;
for (typeindex, any_index) in map1.into_iter().chain(map2) {
if usize::from(typeindex) < current_len {
vec.update(I::from(usize::from(typeindex)), any_index)?;
update_count += 1;
} else {
pushes.push((typeindex, any_index));
}
}
let push_count = pushes.len();
if !pushes.is_empty() {
pushes.sort_unstable_by_key(|(typeindex, _)| *typeindex);
for (_, any_index) in pushes {
vec.push(any_index);
}
}
Ok((update_count, push_count))
}

View File

@@ -92,6 +92,11 @@ impl<T> AddressTypeToTypeIndexMap<T> {
self.0.into_iter()
}
/// Consume and return the inner ByAddressType.
pub fn into_inner(self) -> ByAddressType<FxHashMap<TypeIndex, T>> {
self.0
}
/// Iterate mutably over entries by address type.
pub fn iter_mut(&mut self) -> impl Iterator<Item = (OutputType, &mut FxHashMap<TypeIndex, T>)> {
self.0.iter_mut()

View File

@@ -3,6 +3,7 @@ use brk_types::{
AnyAddressIndex, EmptyAddressData, EmptyAddressIndex, LoadedAddressData, LoadedAddressIndex,
OutputType, TypeIndex,
};
use vecdb::AnyVec;
use crate::distribution::{AddressTypeToTypeIndexMap, AddressesDataVecs};
@@ -51,9 +52,12 @@ pub fn process_loaded_addresses(
addresses_data.loaded.update(index, data)?;
}
// Phase 3: Pushes (fills holes, then grows)
let mut result = AddressTypeToTypeIndexMap::default();
for (address_type, typeindex, data) in pushes {
// Phase 3: Pushes (fill holes first, then pure pushes)
let mut result = AddressTypeToTypeIndexMap::with_capacity(pushes.len() / 4);
let holes_count = addresses_data.loaded.holes().len();
let mut pushes_iter = pushes.into_iter();
for (address_type, typeindex, data) in pushes_iter.by_ref().take(holes_count) {
let index = addresses_data.loaded.fill_first_hole_or_push(data)?;
result
.get_mut(address_type)
@@ -61,6 +65,18 @@ pub fn process_loaded_addresses(
.insert(typeindex, AnyAddressIndex::from(index));
}
// Pure pushes - no holes remain
addresses_data.loaded.reserve_pushed(pushes_iter.len());
let mut next_index = addresses_data.loaded.len();
for (address_type, typeindex, data) in pushes_iter {
addresses_data.loaded.push(data);
result
.get_mut(address_type)
.unwrap()
.insert(typeindex, AnyAddressIndex::from(LoadedAddressIndex::from(next_index)));
next_index += 1;
}
Ok(result)
}
@@ -107,9 +123,12 @@ pub fn process_empty_addresses(
addresses_data.empty.update(index, data)?;
}
// Phase 3: Pushes (fills holes, then grows)
let mut result = AddressTypeToTypeIndexMap::default();
for (address_type, typeindex, data) in pushes {
// Phase 3: Pushes (fill holes first, then pure pushes)
let mut result = AddressTypeToTypeIndexMap::with_capacity(pushes.len() / 4);
let holes_count = addresses_data.empty.holes().len();
let mut pushes_iter = pushes.into_iter();
for (address_type, typeindex, data) in pushes_iter.by_ref().take(holes_count) {
let index = addresses_data.empty.fill_first_hole_or_push(data)?;
result
.get_mut(address_type)
@@ -117,5 +136,17 @@ pub fn process_empty_addresses(
.insert(typeindex, AnyAddressIndex::from(index));
}
// Pure pushes - no holes remain
addresses_data.empty.reserve_pushed(pushes_iter.len());
let mut next_index = addresses_data.empty.len();
for (address_type, typeindex, data) in pushes_iter {
addresses_data.empty.push(data);
result
.get_mut(address_type)
.unwrap()
.insert(typeindex, AnyAddressIndex::from(EmptyAddressIndex::from(next_index)));
next_index += 1;
}
Ok(result)
}

View File

@@ -8,7 +8,7 @@ use rayon::prelude::*;
use vecdb::{AnyStoredVec, AnyVec, Database, Exit, GenericStoredVec, IterableVec};
use crate::{
ComputeIndexes, distribution::state::AddressCohortState, indexes, internal::ComputedBlockLast,
ComputeIndexes, distribution::state::AddressCohortState, indexes, internal::ComputedFromHeightLast,
price,
};
@@ -32,7 +32,7 @@ pub struct AddressCohortVecs {
#[traversable(flatten)]
pub metrics: CohortMetrics,
pub addr_count: ComputedBlockLast<StoredU64>,
pub addr_count: ComputedFromHeightLast<StoredU64>,
}
impl AddressCohortVecs {
@@ -73,7 +73,7 @@ impl AddressCohortVecs {
metrics: CohortMetrics::forced_import(&cfg, all_supply)?,
addr_count: ComputedBlockLast::forced_import(
addr_count: ComputedFromHeightLast::forced_import(
db,
&cfg.name("addr_count"),
version + VERSION,

View File

@@ -33,15 +33,12 @@ pub fn process_address_updates(
) -> Result<()> {
info!("Processing address updates...");
let i = Instant::now();
let empty_result = process_empty_addresses(addresses_data, empty_updates)?;
let loaded_result = process_loaded_addresses(addresses_data, loaded_updates)?;
let all_updates = empty_result.merge(loaded_result);
address_indexes.par_batch_update(empty_result, loaded_result)?;
for (address_type, sorted) in all_updates.into_sorted_iter() {
for (typeindex, any_index) in sorted {
address_indexes.update_or_push(address_type, typeindex, any_index)?;
}
}
info!("Processed address updates in {:?}", i.elapsed());
Ok(())
}

View File

@@ -6,7 +6,7 @@ use vecdb::{AnyStoredVec, AnyVec, EagerVec, Exit, GenericStoredVec, ImportableVe
use crate::{
ComputeIndexes, indexes,
internal::{ComputedBlockSumCum, LazyComputedValueBlockSumCum},
internal::{ComputedFromHeightSumCum, LazyComputedValueFromHeightSumCum},
};
use super::ImportConfig;
@@ -15,7 +15,7 @@ use super::ImportConfig;
#[derive(Clone, Traversable)]
pub struct ActivityMetrics {
/// Total satoshis sent at each height + derived indexes
pub sent: LazyComputedValueBlockSumCum,
pub sent: LazyComputedValueFromHeightSumCum,
/// Satoshi-blocks destroyed (supply * blocks_old when spent)
pub satblocks_destroyed: EagerVec<PcoVec<Height, Sats>>,
@@ -24,17 +24,17 @@ pub struct ActivityMetrics {
pub satdays_destroyed: EagerVec<PcoVec<Height, Sats>>,
/// Coin-blocks destroyed (in BTC rather than sats)
pub coinblocks_destroyed: ComputedBlockSumCum<StoredF64>,
pub coinblocks_destroyed: ComputedFromHeightSumCum<StoredF64>,
/// Coin-days destroyed (in BTC rather than sats)
pub coindays_destroyed: ComputedBlockSumCum<StoredF64>,
pub coindays_destroyed: ComputedFromHeightSumCum<StoredF64>,
}
impl ActivityMetrics {
/// Import activity metrics from database.
pub fn forced_import(cfg: &ImportConfig) -> Result<Self> {
Ok(Self {
sent: LazyComputedValueBlockSumCum::forced_import(
sent: LazyComputedValueFromHeightSumCum::forced_import(
cfg.db,
&cfg.name("sent"),
cfg.version,
@@ -54,14 +54,14 @@ impl ActivityMetrics {
cfg.version,
)?,
coinblocks_destroyed: ComputedBlockSumCum::forced_import(
coinblocks_destroyed: ComputedFromHeightSumCum::forced_import(
cfg.db,
&cfg.name("coinblocks_destroyed"),
cfg.version,
cfg.indexes,
)?,
coindays_destroyed: ComputedBlockSumCum::forced_import(
coindays_destroyed: ComputedFromHeightSumCum::forced_import(
cfg.db,
&cfg.name("coindays_destroyed"),
cfg.version,

View File

@@ -8,7 +8,7 @@ use crate::{
ComputeIndexes,
distribution::state::CohortState,
indexes,
internal::{ComputedBlockLast, CostBasisPercentiles},
internal::{ComputedFromHeightLast, CostBasisPercentiles},
};
use super::ImportConfig;
@@ -17,10 +17,10 @@ use super::ImportConfig;
#[derive(Clone, Traversable)]
pub struct CostBasisMetrics {
/// Minimum cost basis for any UTXO at this height
pub min: ComputedBlockLast<Dollars>,
pub min: ComputedFromHeightLast<Dollars>,
/// Maximum cost basis for any UTXO at this height
pub max: ComputedBlockLast<Dollars>,
pub max: ComputedFromHeightLast<Dollars>,
/// Cost basis distribution percentiles (median, quartiles, etc.)
pub percentiles: Option<CostBasisPercentiles>,
@@ -32,13 +32,13 @@ impl CostBasisMetrics {
let extended = cfg.extended();
Ok(Self {
min: ComputedBlockLast::forced_import(
min: ComputedFromHeightLast::forced_import(
cfg.db,
&cfg.name("min_cost_basis"),
cfg.version,
cfg.indexes,
)?,
max: ComputedBlockLast::forced_import(
max: ComputedFromHeightLast::forced_import(
cfg.db,
&cfg.name("max_cost_basis"),
cfg.version,

View File

@@ -313,7 +313,7 @@ impl CohortMetrics {
exit: &Exit,
) -> Result<()> {
self.supply
.compute_rest_part1(indexes, price, starting_indexes, exit)?;
.compute_rest_part1(indexes, starting_indexes, exit)?;
self.outputs.compute_rest(indexes, starting_indexes, exit)?;
self.activity
.compute_rest_part1(indexes, starting_indexes, exit)?;

View File

@@ -4,21 +4,21 @@ use brk_types::{Height, StoredU64};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, AnyVec, Exit, GenericStoredVec};
use crate::{ComputeIndexes, indexes, internal::ComputedBlockLast};
use crate::{ComputeIndexes, indexes, internal::ComputedFromHeightLast};
use super::ImportConfig;
/// Output metrics for a cohort.
#[derive(Clone, Traversable)]
pub struct OutputsMetrics {
pub utxo_count: ComputedBlockLast<StoredU64>,
pub utxo_count: ComputedFromHeightLast<StoredU64>,
}
impl OutputsMetrics {
/// Import output metrics from database.
pub fn forced_import(cfg: &ImportConfig) -> Result<Self> {
Ok(Self {
utxo_count: ComputedBlockLast::forced_import(
utxo_count: ComputedFromHeightLast::forced_import(
cfg.db,
&cfg.name("utxo_count"),
cfg.version,

View File

@@ -12,9 +12,9 @@ use crate::{
distribution::state::RealizedState,
indexes,
internal::{
ComputedBlockLast, ComputedBlockSum, ComputedBlockSumCum, ComputedDateLast,
ComputedRatioVecsDate, DollarsMinus, LazyBinaryBlockSum, LazyBinaryBlockSumCum,
LazyBlockSum, LazyBlockSumCum, LazyDateLast, PercentageDollarsF32, StoredF32Identity,
ComputedFromHeightLast, ComputedFromHeightSum, ComputedFromHeightSumCum, ComputedFromDateLast,
ComputedFromDateRatio, DollarsMinus, LazyBinaryFromHeightSum, LazyBinaryFromHeightSumCum,
LazyFromHeightSum, LazyFromHeightSumCum, LazyFromDateLast, PercentageDollarsF32, StoredF32Identity,
},
price,
};
@@ -25,39 +25,39 @@ use super::ImportConfig;
#[derive(Clone, Traversable)]
pub struct RealizedMetrics {
// === Realized Cap ===
pub realized_cap: ComputedBlockLast<Dollars>,
pub realized_price: ComputedBlockLast<Dollars>,
pub realized_price_extra: ComputedRatioVecsDate,
pub realized_cap_rel_to_own_market_cap: Option<ComputedBlockLast<StoredF32>>,
pub realized_cap_30d_delta: ComputedDateLast<Dollars>,
pub realized_cap: ComputedFromHeightLast<Dollars>,
pub realized_price: ComputedFromHeightLast<Dollars>,
pub realized_price_extra: ComputedFromDateRatio,
pub realized_cap_rel_to_own_market_cap: Option<ComputedFromHeightLast<StoredF32>>,
pub realized_cap_30d_delta: ComputedFromDateLast<Dollars>,
// === MVRV (Market Value to Realized Value) ===
// Proxy for realized_price_extra.ratio (close / realized_price = market_cap / realized_cap)
pub mvrv: LazyDateLast<StoredF32>,
pub mvrv: LazyFromDateLast<StoredF32>,
// === Realized Profit/Loss ===
pub realized_profit: ComputedBlockSumCum<Dollars>,
pub realized_loss: ComputedBlockSumCum<Dollars>,
pub neg_realized_loss: LazyBlockSumCum<Dollars>,
pub net_realized_pnl: ComputedBlockSumCum<Dollars>,
pub realized_value: ComputedBlockSum<Dollars>,
pub realized_profit: ComputedFromHeightSumCum<Dollars>,
pub realized_loss: ComputedFromHeightSumCum<Dollars>,
pub neg_realized_loss: LazyFromHeightSumCum<Dollars>,
pub net_realized_pnl: ComputedFromHeightSumCum<Dollars>,
pub realized_value: ComputedFromHeightSum<Dollars>,
// === Realized vs Realized Cap Ratios (lazy) ===
pub realized_profit_rel_to_realized_cap: LazyBinaryBlockSumCum<StoredF32, Dollars, Dollars>,
pub realized_loss_rel_to_realized_cap: LazyBinaryBlockSumCum<StoredF32, Dollars, Dollars>,
pub net_realized_pnl_rel_to_realized_cap: LazyBinaryBlockSumCum<StoredF32, Dollars, Dollars>,
pub realized_profit_rel_to_realized_cap: LazyBinaryFromHeightSumCum<StoredF32, Dollars, Dollars>,
pub realized_loss_rel_to_realized_cap: LazyBinaryFromHeightSumCum<StoredF32, Dollars, Dollars>,
pub net_realized_pnl_rel_to_realized_cap: LazyBinaryFromHeightSumCum<StoredF32, Dollars, Dollars>,
// === Total Realized PnL ===
pub total_realized_pnl: LazyBlockSum<Dollars>,
pub total_realized_pnl: LazyFromHeightSum<Dollars>,
pub realized_profit_to_loss_ratio: Option<EagerVec<PcoVec<DateIndex, StoredF64>>>,
// === Value Created/Destroyed ===
pub value_created: ComputedBlockSum<Dollars>,
pub value_destroyed: ComputedBlockSum<Dollars>,
pub value_created: ComputedFromHeightSum<Dollars>,
pub value_destroyed: ComputedFromHeightSum<Dollars>,
// === Adjusted Value (lazy: cohort - up_to_1h) ===
pub adjusted_value_created: Option<LazyBinaryBlockSum<Dollars, Dollars, Dollars>>,
pub adjusted_value_destroyed: Option<LazyBinaryBlockSum<Dollars, Dollars, Dollars>>,
pub adjusted_value_created: Option<LazyBinaryFromHeightSum<Dollars, Dollars, Dollars>>,
pub adjusted_value_destroyed: Option<LazyBinaryFromHeightSum<Dollars, Dollars, Dollars>>,
// === SOPR (Spent Output Profit Ratio) ===
pub sopr: EagerVec<PcoVec<DateIndex, StoredF64>>,
@@ -73,9 +73,9 @@ pub struct RealizedMetrics {
pub sell_side_risk_ratio_30d_ema: EagerVec<PcoVec<DateIndex, StoredF32>>,
// === Net Realized PnL Deltas ===
pub net_realized_pnl_cumulative_30d_delta: ComputedDateLast<Dollars>,
pub net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: ComputedDateLast<StoredF32>,
pub net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: ComputedDateLast<StoredF32>,
pub net_realized_pnl_cumulative_30d_delta: ComputedFromDateLast<Dollars>,
pub net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: ComputedFromDateLast<StoredF32>,
pub net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: ComputedFromDateLast<StoredF32>,
}
impl RealizedMetrics {
@@ -87,35 +87,35 @@ impl RealizedMetrics {
let compute_adjusted = cfg.compute_adjusted();
// Import combined types using forced_import which handles height + derived
let realized_cap = ComputedBlockLast::forced_import(
let realized_cap = ComputedFromHeightLast::forced_import(
cfg.db,
&cfg.name("realized_cap"),
cfg.version,
cfg.indexes,
)?;
let realized_profit = ComputedBlockSumCum::forced_import(
let realized_profit = ComputedFromHeightSumCum::forced_import(
cfg.db,
&cfg.name("realized_profit"),
cfg.version,
cfg.indexes,
)?;
let realized_loss = ComputedBlockSumCum::forced_import(
let realized_loss = ComputedFromHeightSumCum::forced_import(
cfg.db,
&cfg.name("realized_loss"),
cfg.version,
cfg.indexes,
)?;
let neg_realized_loss = LazyBlockSumCum::from_computed::<Negate>(
let neg_realized_loss = LazyFromHeightSumCum::from_computed::<Negate>(
&cfg.name("neg_realized_loss"),
cfg.version + v1,
realized_loss.height.boxed_clone(),
&realized_loss,
);
let net_realized_pnl = ComputedBlockSumCum::forced_import(
let net_realized_pnl = ComputedFromHeightSumCum::forced_import(
cfg.db,
&cfg.name("net_realized_pnl"),
cfg.version,
@@ -123,7 +123,7 @@ impl RealizedMetrics {
)?;
// realized_value is the source for total_realized_pnl (they're identical)
let realized_value = ComputedBlockSum::forced_import(
let realized_value = ComputedFromHeightSum::forced_import(
cfg.db,
&cfg.name("realized_value"),
cfg.version,
@@ -131,7 +131,7 @@ impl RealizedMetrics {
)?;
// total_realized_pnl is a lazy alias to realized_value
let total_realized_pnl = LazyBlockSum::from_computed::<Ident>(
let total_realized_pnl = LazyFromHeightSum::from_computed::<Ident>(
&cfg.name("total_realized_pnl"),
cfg.version + v1,
realized_value.height.boxed_clone(),
@@ -140,7 +140,7 @@ impl RealizedMetrics {
// Construct lazy ratio vecs
let realized_profit_rel_to_realized_cap =
LazyBinaryBlockSumCum::from_computed_last::<PercentageDollarsF32>(
LazyBinaryFromHeightSumCum::from_computed_last::<PercentageDollarsF32>(
&cfg.name("realized_profit_rel_to_realized_cap"),
cfg.version + v1,
realized_profit.height.boxed_clone(),
@@ -150,7 +150,7 @@ impl RealizedMetrics {
);
let realized_loss_rel_to_realized_cap =
LazyBinaryBlockSumCum::from_computed_last::<PercentageDollarsF32>(
LazyBinaryFromHeightSumCum::from_computed_last::<PercentageDollarsF32>(
&cfg.name("realized_loss_rel_to_realized_cap"),
cfg.version + v1,
realized_loss.height.boxed_clone(),
@@ -160,7 +160,7 @@ impl RealizedMetrics {
);
let net_realized_pnl_rel_to_realized_cap =
LazyBinaryBlockSumCum::from_computed_last::<PercentageDollarsF32>(
LazyBinaryFromHeightSumCum::from_computed_last::<PercentageDollarsF32>(
&cfg.name("net_realized_pnl_rel_to_realized_cap"),
cfg.version + v1,
net_realized_pnl.height.boxed_clone(),
@@ -169,21 +169,21 @@ impl RealizedMetrics {
&realized_cap,
);
let realized_price = ComputedBlockLast::forced_import(
let realized_price = ComputedFromHeightLast::forced_import(
cfg.db,
&cfg.name("realized_price"),
cfg.version + v1,
cfg.indexes,
)?;
let value_created = ComputedBlockSum::forced_import(
let value_created = ComputedFromHeightSum::forced_import(
cfg.db,
&cfg.name("value_created"),
cfg.version,
cfg.indexes,
)?;
let value_destroyed = ComputedBlockSum::forced_import(
let value_destroyed = ComputedFromHeightSum::forced_import(
cfg.db,
&cfg.name("value_destroyed"),
cfg.version,
@@ -194,7 +194,7 @@ impl RealizedMetrics {
let adjusted_value_created =
(compute_adjusted && cfg.up_to_1h_realized.is_some()).then(|| {
let up_to_1h = cfg.up_to_1h_realized.unwrap();
LazyBinaryBlockSum::from_computed::<DollarsMinus>(
LazyBinaryFromHeightSum::from_computed::<DollarsMinus>(
&cfg.name("adjusted_value_created"),
cfg.version,
&value_created,
@@ -204,7 +204,7 @@ impl RealizedMetrics {
let adjusted_value_destroyed =
(compute_adjusted && cfg.up_to_1h_realized.is_some()).then(|| {
let up_to_1h = cfg.up_to_1h_realized.unwrap();
LazyBinaryBlockSum::from_computed::<DollarsMinus>(
LazyBinaryFromHeightSum::from_computed::<DollarsMinus>(
&cfg.name("adjusted_value_destroyed"),
cfg.version,
&value_destroyed,
@@ -213,7 +213,7 @@ impl RealizedMetrics {
});
// Create realized_price_extra first so we can reference its ratio for MVRV proxy
let realized_price_extra = ComputedRatioVecsDate::forced_import(
let realized_price_extra = ComputedFromDateRatio::forced_import(
cfg.db,
&cfg.name("realized_price"),
Some(&realized_price),
@@ -225,7 +225,7 @@ impl RealizedMetrics {
// MVRV is a lazy proxy for realized_price_extra.ratio
// ratio = close / realized_price = market_cap / realized_cap = MVRV
let mvrv = LazyDateLast::from_source::<StoredF32Identity>(
let mvrv = LazyFromDateLast::from_source::<StoredF32Identity>(
&cfg.name("mvrv"),
cfg.version,
&realized_price_extra.ratio,
@@ -238,7 +238,7 @@ impl RealizedMetrics {
realized_price_extra,
realized_cap_rel_to_own_market_cap: extended
.then(|| {
ComputedBlockLast::forced_import(
ComputedFromHeightLast::forced_import(
cfg.db,
&cfg.name("realized_cap_rel_to_own_market_cap"),
cfg.version,
@@ -246,7 +246,7 @@ impl RealizedMetrics {
)
})
.transpose()?,
realized_cap_30d_delta: ComputedDateLast::forced_import(
realized_cap_30d_delta: ComputedFromDateLast::forced_import(
cfg.db,
&cfg.name("realized_cap_30d_delta"),
cfg.version,
@@ -338,21 +338,21 @@ impl RealizedMetrics {
)?,
// === Net Realized PnL Deltas ===
net_realized_pnl_cumulative_30d_delta: ComputedDateLast::forced_import(
net_realized_pnl_cumulative_30d_delta: ComputedFromDateLast::forced_import(
cfg.db,
&cfg.name("net_realized_pnl_cumulative_30d_delta"),
cfg.version + v3,
cfg.indexes,
)?,
net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap:
ComputedDateLast::forced_import(
ComputedFromDateLast::forced_import(
cfg.db,
&cfg.name("net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap"),
cfg.version + v3,
cfg.indexes,
)?,
net_realized_pnl_cumulative_30d_delta_rel_to_market_cap:
ComputedDateLast::forced_import(
ComputedFromDateLast::forced_import(
cfg.db,
&cfg.name("net_realized_pnl_cumulative_30d_delta_rel_to_market_cap"),
cfg.version + v3,

View File

@@ -4,7 +4,7 @@ use brk_types::{Dollars, Sats, StoredF32, StoredF64, Version};
use vecdb::IterableCloneableVec;
use crate::internal::{
LazyBinaryBlockLast, LazyBinaryDateLast, NegPercentageDollarsF32, NegRatio32,
LazyBinaryFromHeightLast, LazyBinaryFromDateLast, NegPercentageDollarsF32, NegRatio32,
PercentageDollarsF32, PercentageSatsF64, Ratio32,
};
@@ -15,49 +15,49 @@ use super::{ImportConfig, SupplyMetrics, UnrealizedMetrics};
#[derive(Clone, Traversable)]
pub struct RelativeMetrics {
// === Supply Relative to Circulating Supply (lazy from global supply) ===
pub supply_rel_to_circulating_supply: Option<LazyBinaryDateLast<StoredF64, Sats, Sats>>,
pub supply_rel_to_circulating_supply: Option<LazyBinaryFromDateLast<StoredF64, Sats, Sats>>,
// === Supply in Profit/Loss Relative to Own Supply (lazy) ===
pub supply_in_profit_rel_to_own_supply: LazyBinaryBlockLast<StoredF64, Sats, Sats>,
pub supply_in_loss_rel_to_own_supply: LazyBinaryBlockLast<StoredF64, Sats, Sats>,
pub supply_in_profit_rel_to_own_supply: LazyBinaryFromHeightLast<StoredF64, Sats, Sats>,
pub supply_in_loss_rel_to_own_supply: LazyBinaryFromHeightLast<StoredF64, Sats, Sats>,
// === Supply in Profit/Loss Relative to Circulating Supply (lazy from global supply) ===
pub supply_in_profit_rel_to_circulating_supply:
Option<LazyBinaryBlockLast<StoredF64, Sats, Sats>>,
Option<LazyBinaryFromHeightLast<StoredF64, Sats, Sats>>,
pub supply_in_loss_rel_to_circulating_supply:
Option<LazyBinaryBlockLast<StoredF64, Sats, Sats>>,
Option<LazyBinaryFromHeightLast<StoredF64, Sats, Sats>>,
// === Unrealized vs Market Cap (lazy from global market cap) ===
pub unrealized_profit_rel_to_market_cap:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
pub unrealized_loss_rel_to_market_cap: Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
pub unrealized_loss_rel_to_market_cap: Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
pub neg_unrealized_loss_rel_to_market_cap:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
pub net_unrealized_pnl_rel_to_market_cap:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
// === NUPL (Net Unrealized Profit/Loss) ===
pub nupl: Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
pub nupl: Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
// === Unrealized vs Own Market Cap (lazy) ===
pub unrealized_profit_rel_to_own_market_cap:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
pub unrealized_loss_rel_to_own_market_cap:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
pub neg_unrealized_loss_rel_to_own_market_cap:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
pub net_unrealized_pnl_rel_to_own_market_cap:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
// === Unrealized vs Own Total Unrealized PnL (lazy) ===
pub unrealized_profit_rel_to_own_total_unrealized_pnl:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
pub unrealized_loss_rel_to_own_total_unrealized_pnl:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
pub neg_unrealized_loss_rel_to_own_total_unrealized_pnl:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
pub net_unrealized_pnl_rel_to_own_total_unrealized_pnl:
Option<LazyBinaryBlockLast<StoredF32, Dollars, Dollars>>,
Option<LazyBinaryFromHeightLast<StoredF32, Dollars, Dollars>>,
}
impl RelativeMetrics {
@@ -91,7 +91,7 @@ impl RelativeMetrics {
supply_rel_to_circulating_supply: (compute_rel_to_all
&& global_supply_sats_dates.is_some())
.then(|| {
LazyBinaryDateLast::from_both_derived_last::<PercentageSatsF64>(
LazyBinaryFromDateLast::from_both_derived_last::<PercentageSatsF64>(
&cfg.name("supply_rel_to_circulating_supply"),
cfg.version + v1,
supply.total.sats.rest.dateindex.boxed_clone(),
@@ -103,7 +103,7 @@ impl RelativeMetrics {
// === Supply in Profit/Loss Relative to Own Supply (lazy) ===
supply_in_profit_rel_to_own_supply:
LazyBinaryBlockLast::from_height_difficultyepoch_dates::<PercentageSatsF64>(
LazyBinaryFromHeightLast::from_height_difficultyepoch_dates::<PercentageSatsF64>(
&cfg.name("supply_in_profit_rel_to_own_supply"),
cfg.version + v1,
unrealized.supply_in_profit.height.boxed_clone(),
@@ -120,7 +120,7 @@ impl RelativeMetrics {
&supply.total.sats.rest.dates,
),
supply_in_loss_rel_to_own_supply:
LazyBinaryBlockLast::from_height_difficultyepoch_dates::<PercentageSatsF64>(
LazyBinaryFromHeightLast::from_height_difficultyepoch_dates::<PercentageSatsF64>(
&cfg.name("supply_in_loss_rel_to_own_supply"),
cfg.version + v1,
unrealized.supply_in_loss.height.boxed_clone(),
@@ -141,7 +141,7 @@ impl RelativeMetrics {
supply_in_profit_rel_to_circulating_supply: (compute_rel_to_all
&& global_supply_sats_height.is_some())
.then(|| {
LazyBinaryBlockLast::from_height_difficultyepoch_dates::<PercentageSatsF64>(
LazyBinaryFromHeightLast::from_height_difficultyepoch_dates::<PercentageSatsF64>(
&cfg.name("supply_in_profit_rel_to_circulating_supply"),
cfg.version + v1,
unrealized.supply_in_profit.height.boxed_clone(),
@@ -161,7 +161,7 @@ impl RelativeMetrics {
supply_in_loss_rel_to_circulating_supply: (compute_rel_to_all
&& global_supply_sats_height.is_some())
.then(|| {
LazyBinaryBlockLast::from_height_difficultyepoch_dates::<PercentageSatsF64>(
LazyBinaryFromHeightLast::from_height_difficultyepoch_dates::<PercentageSatsF64>(
&cfg.name("supply_in_loss_rel_to_circulating_supply"),
cfg.version + v1,
unrealized.supply_in_loss.height.boxed_clone(),
@@ -182,8 +182,10 @@ impl RelativeMetrics {
// === Unrealized vs Market Cap (lazy from global market cap) ===
unrealized_profit_rel_to_market_cap:
global_market_cap.map(|mc| {
LazyBinaryBlockLast::from_computed_height_date_and_block_last::<
LazyBinaryFromHeightLast::from_computed_height_date_and_lazy_binary_block_last::<
PercentageDollarsF32,
_,
_,
>(
&cfg.name("unrealized_profit_rel_to_market_cap"),
cfg.version + v2,
@@ -193,8 +195,10 @@ impl RelativeMetrics {
}),
unrealized_loss_rel_to_market_cap:
global_market_cap.map(|mc| {
LazyBinaryBlockLast::from_computed_height_date_and_block_last::<
LazyBinaryFromHeightLast::from_computed_height_date_and_lazy_binary_block_last::<
PercentageDollarsF32,
_,
_,
>(
&cfg.name("unrealized_loss_rel_to_market_cap"),
cfg.version + v2,
@@ -203,8 +207,10 @@ impl RelativeMetrics {
)
}),
neg_unrealized_loss_rel_to_market_cap: global_market_cap.map(|mc| {
LazyBinaryBlockLast::from_computed_height_date_and_block_last::<
LazyBinaryFromHeightLast::from_computed_height_date_and_lazy_binary_block_last::<
NegPercentageDollarsF32,
_,
_,
>(
&cfg.name("neg_unrealized_loss_rel_to_market_cap"),
cfg.version + v2,
@@ -213,10 +219,12 @@ impl RelativeMetrics {
)
}),
net_unrealized_pnl_rel_to_market_cap: global_market_cap.map(|mc| {
LazyBinaryBlockLast::from_binary_block_and_computed_block_last::<
LazyBinaryFromHeightLast::from_binary_block_and_lazy_binary_block_last::<
PercentageDollarsF32,
_,
_,
_,
_,
>(
&cfg.name("net_unrealized_pnl_rel_to_market_cap"),
cfg.version + v2,
@@ -227,10 +235,12 @@ impl RelativeMetrics {
// NUPL is a proxy for net_unrealized_pnl_rel_to_market_cap
nupl: global_market_cap.map(|mc| {
LazyBinaryBlockLast::from_binary_block_and_computed_block_last::<
LazyBinaryFromHeightLast::from_binary_block_and_lazy_binary_block_last::<
PercentageDollarsF32,
_,
_,
_,
_,
>(
&cfg.name("nupl"),
cfg.version + v2,
@@ -243,8 +253,10 @@ impl RelativeMetrics {
unrealized_profit_rel_to_own_market_cap: (extended && compute_rel_to_all)
.then(|| {
own_market_cap.map(|mc| {
LazyBinaryBlockLast::from_computed_height_date_and_block_last::<
LazyBinaryFromHeightLast::from_computed_height_date_and_lazy_binary_block_last::<
PercentageDollarsF32,
_,
_,
>(
&cfg.name("unrealized_profit_rel_to_own_market_cap"),
cfg.version + v2,
@@ -257,8 +269,10 @@ impl RelativeMetrics {
unrealized_loss_rel_to_own_market_cap: (extended && compute_rel_to_all)
.then(|| {
own_market_cap.map(|mc| {
LazyBinaryBlockLast::from_computed_height_date_and_block_last::<
LazyBinaryFromHeightLast::from_computed_height_date_and_lazy_binary_block_last::<
PercentageDollarsF32,
_,
_,
>(
&cfg.name("unrealized_loss_rel_to_own_market_cap"),
cfg.version + v2,
@@ -271,8 +285,10 @@ impl RelativeMetrics {
neg_unrealized_loss_rel_to_own_market_cap: (extended && compute_rel_to_all)
.then(|| {
own_market_cap.map(|mc| {
LazyBinaryBlockLast::from_computed_height_date_and_block_last::<
LazyBinaryFromHeightLast::from_computed_height_date_and_lazy_binary_block_last::<
NegPercentageDollarsF32,
_,
_,
>(
&cfg.name("neg_unrealized_loss_rel_to_own_market_cap"),
cfg.version + v2,
@@ -285,10 +301,12 @@ impl RelativeMetrics {
net_unrealized_pnl_rel_to_own_market_cap: (extended && compute_rel_to_all)
.then(|| {
own_market_cap.map(|mc| {
LazyBinaryBlockLast::from_binary_block_and_computed_block_last::<
LazyBinaryFromHeightLast::from_binary_block_and_lazy_binary_block_last::<
PercentageDollarsF32,
_,
_,
_,
_,
>(
&cfg.name("net_unrealized_pnl_rel_to_own_market_cap"),
cfg.version + v2,
@@ -301,7 +319,7 @@ impl RelativeMetrics {
// === Unrealized vs Own Total Unrealized PnL (lazy, optional) ===
unrealized_profit_rel_to_own_total_unrealized_pnl: extended.then(|| {
LazyBinaryBlockLast::from_computed_height_date_and_binary_block::<Ratio32, _, _>(
LazyBinaryFromHeightLast::from_computed_height_date_and_binary_block::<Ratio32, _, _>(
&cfg.name("unrealized_profit_rel_to_own_total_unrealized_pnl"),
cfg.version,
&unrealized.unrealized_profit,
@@ -309,7 +327,7 @@ impl RelativeMetrics {
)
}),
unrealized_loss_rel_to_own_total_unrealized_pnl: extended.then(|| {
LazyBinaryBlockLast::from_computed_height_date_and_binary_block::<Ratio32, _, _>(
LazyBinaryFromHeightLast::from_computed_height_date_and_binary_block::<Ratio32, _, _>(
&cfg.name("unrealized_loss_rel_to_own_total_unrealized_pnl"),
cfg.version,
&unrealized.unrealized_loss,
@@ -317,7 +335,7 @@ impl RelativeMetrics {
)
}),
neg_unrealized_loss_rel_to_own_total_unrealized_pnl: extended.then(|| {
LazyBinaryBlockLast::from_computed_height_date_and_binary_block::<NegRatio32, _, _>(
LazyBinaryFromHeightLast::from_computed_height_date_and_binary_block::<NegRatio32, _, _>(
&cfg.name("neg_unrealized_loss_rel_to_own_total_unrealized_pnl"),
cfg.version,
&unrealized.unrealized_loss,
@@ -325,7 +343,7 @@ impl RelativeMetrics {
)
}),
net_unrealized_pnl_rel_to_own_total_unrealized_pnl: extended.then(|| {
LazyBinaryBlockLast::from_both_binary_block::<Ratio32, _, _, _, _>(
LazyBinaryFromHeightLast::from_both_binary_block::<Ratio32, _, _, _, _>(
&cfg.name("net_unrealized_pnl_rel_to_own_total_unrealized_pnl"),
cfg.version + v1,
&unrealized.net_unrealized_pnl,

View File

@@ -9,10 +9,9 @@ use vecdb::{AnyStoredVec, AnyVec, Exit, GenericStoredVec};
use crate::{
indexes,
internal::{
HalfClosePriceTimesSats, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyBinaryValueBlockLast,
ValueBlockLast,
HalfClosePriceTimesSats, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyBinaryValueFromHeightLast,
ValueFromHeightLast,
},
price,
};
use super::ImportConfig;
@@ -20,24 +19,22 @@ use super::ImportConfig;
/// Supply metrics for a cohort.
#[derive(Clone, Traversable)]
pub struct SupplyMetrics {
pub total: ValueBlockLast,
pub halved: LazyBinaryValueBlockLast,
pub total: ValueFromHeightLast,
pub halved: LazyBinaryValueFromHeightLast,
}
impl SupplyMetrics {
/// Import supply metrics from database.
pub fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let compute_dollars = cfg.compute_dollars();
let supply = ValueBlockLast::forced_import(
let supply = ValueFromHeightLast::forced_import(
cfg.db,
&cfg.name("supply"),
cfg.version,
cfg.indexes,
compute_dollars,
cfg.price,
)?;
let supply_half = LazyBinaryValueBlockLast::from_block_source::<
let supply_half = LazyBinaryValueFromHeightLast::from_block_source::<
HalveSats,
HalveSatsToBitcoin,
HalfClosePriceTimesSats,
@@ -100,11 +97,9 @@ impl SupplyMetrics {
pub fn compute_rest_part1(
&mut self,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &ComputeIndexes,
exit: &Exit,
) -> Result<()> {
self.total
.compute_rest(indexes, price, starting_indexes, exit)
self.total.compute_rest(indexes, starting_indexes, exit)
}
}

View File

@@ -8,8 +8,8 @@ use crate::{
ComputeIndexes,
distribution::state::UnrealizedState,
internal::{
ComputedHeightDateLast, DollarsMinus, DollarsPlus, LazyBinaryBlockLast, LazyBlockLast,
ValueHeightDateLast,
ComputedFromHeightAndDateLast, DollarsMinus, DollarsPlus, LazyBinaryFromHeightLast, LazyFromHeightLast,
ValueFromHeightAndDateLast,
},
};
@@ -19,19 +19,19 @@ use super::ImportConfig;
#[derive(Clone, Traversable)]
pub struct UnrealizedMetrics {
// === Supply in Profit/Loss ===
pub supply_in_profit: ValueHeightDateLast,
pub supply_in_loss: ValueHeightDateLast,
pub supply_in_profit: ValueFromHeightAndDateLast,
pub supply_in_loss: ValueFromHeightAndDateLast,
// === Unrealized Profit/Loss ===
pub unrealized_profit: ComputedHeightDateLast<Dollars>,
pub unrealized_loss: ComputedHeightDateLast<Dollars>,
pub unrealized_profit: ComputedFromHeightAndDateLast<Dollars>,
pub unrealized_loss: ComputedFromHeightAndDateLast<Dollars>,
// === Negated ===
pub neg_unrealized_loss: LazyBlockLast<Dollars>,
pub neg_unrealized_loss: LazyFromHeightLast<Dollars>,
// === Net and Total ===
pub net_unrealized_pnl: LazyBinaryBlockLast<Dollars>,
pub total_unrealized_pnl: LazyBinaryBlockLast<Dollars>,
pub net_unrealized_pnl: LazyBinaryFromHeightLast<Dollars>,
pub total_unrealized_pnl: LazyBinaryFromHeightLast<Dollars>,
}
impl UnrealizedMetrics {
@@ -40,7 +40,7 @@ impl UnrealizedMetrics {
let compute_dollars = cfg.compute_dollars();
// === Supply in Profit/Loss ===
let supply_in_profit = ValueHeightDateLast::forced_import(
let supply_in_profit = ValueFromHeightAndDateLast::forced_import(
cfg.db,
&cfg.name("supply_in_profit"),
cfg.version,
@@ -48,7 +48,7 @@ impl UnrealizedMetrics {
cfg.indexes,
cfg.price,
)?;
let supply_in_loss = ValueHeightDateLast::forced_import(
let supply_in_loss = ValueFromHeightAndDateLast::forced_import(
cfg.db,
&cfg.name("supply_in_loss"),
cfg.version,
@@ -58,13 +58,13 @@ impl UnrealizedMetrics {
)?;
// === Unrealized Profit/Loss ===
let unrealized_profit = ComputedHeightDateLast::forced_import(
let unrealized_profit = ComputedFromHeightAndDateLast::forced_import(
cfg.db,
&cfg.name("unrealized_profit"),
cfg.version,
cfg.indexes,
)?;
let unrealized_loss = ComputedHeightDateLast::forced_import(
let unrealized_loss = ComputedFromHeightAndDateLast::forced_import(
cfg.db,
&cfg.name("unrealized_loss"),
cfg.version,
@@ -72,20 +72,20 @@ impl UnrealizedMetrics {
)?;
// === Negated ===
let neg_unrealized_loss = LazyBlockLast::from_computed_height_date::<Negate>(
let neg_unrealized_loss = LazyFromHeightLast::from_computed_height_date::<Negate>(
&cfg.name("neg_unrealized_loss"),
cfg.version,
&unrealized_loss,
);
// === Net and Total ===
let net_unrealized_pnl = LazyBinaryBlockLast::from_computed_height_date_last::<DollarsMinus>(
let net_unrealized_pnl = LazyBinaryFromHeightLast::from_computed_height_date_last::<DollarsMinus>(
&cfg.name("net_unrealized_pnl"),
cfg.version,
&unrealized_profit,
&unrealized_loss,
);
let total_unrealized_pnl = LazyBinaryBlockLast::from_computed_height_date_last::<DollarsPlus>(
let total_unrealized_pnl = LazyBinaryFromHeightLast::from_computed_height_date_last::<DollarsPlus>(
&cfg.name("total_unrealized_pnl"),
cfg.version,
&unrealized_profit,

View File

@@ -43,9 +43,9 @@ pub struct Vecs {
pub addr_count: AddrCountVecs,
pub empty_addr_count: AddrCountVecs,
pub loadedaddressindex_to_loadedaddressindex:
pub loadedaddressindex:
LazyVecFrom1<LoadedAddressIndex, LoadedAddressIndex, LoadedAddressIndex, LoadedAddressData>,
pub emptyaddressindex_to_emptyaddressindex:
pub emptyaddressindex:
LazyVecFrom1<EmptyAddressIndex, EmptyAddressIndex, EmptyAddressIndex, EmptyAddressData>,
}
@@ -90,13 +90,13 @@ impl Vecs {
)?;
// Identity mappings for traversable
let loadedaddressindex_to_loadedaddressindex = LazyVecFrom1::init(
let loadedaddressindex = LazyVecFrom1::init(
"loadedaddressindex",
version,
loadedaddressindex_to_loadedaddressdata.boxed_clone(),
|index, _| Some(index),
);
let emptyaddressindex_to_emptyaddressindex = LazyVecFrom1::init(
let emptyaddressindex = LazyVecFrom1::init(
"emptyaddressindex",
version,
emptyaddressindex_to_emptyaddressdata.boxed_clone(),
@@ -125,8 +125,8 @@ impl Vecs {
loaded: loadedaddressindex_to_loadedaddressdata,
empty: emptyaddressindex_to_emptyaddressdata,
},
loadedaddressindex_to_loadedaddressindex,
emptyaddressindex_to_emptyaddressindex,
loadedaddressindex,
emptyaddressindex,
db,
};