website: snapshot

This commit is contained in:
nym21
2026-01-23 22:03:01 +01:00
parent f7bfe5ecaa
commit 9b706dfaee
49 changed files with 631818 additions and 1298 deletions

View File

@@ -30,7 +30,7 @@ where
pub dates: LazyDateDerivedFull<T>,
}
const VERSION: Version = Version::ZERO;
const VERSION: Version = Version::ONE;
impl<T> TxDerivedFull<T>
where
@@ -111,7 +111,7 @@ where
self.dateindex.compute(
starting_indexes.dateindex,
&self.height.average().0,
&self.height.sum().0,
&indexes.dateindex.first_height,
&indexes.dateindex.height_count,
exit,

View File

@@ -14,6 +14,7 @@ pub const DCA_CLASS_YEARS: ByDcaClass<u16> = ByDcaClass {
_2023: 2023,
_2024: 2024,
_2025: 2025,
_2026: 2026,
};
/// DCA class names
@@ -29,6 +30,7 @@ pub const DCA_CLASS_NAMES: ByDcaClass<&'static str> = ByDcaClass {
_2023: "dca_class_2023",
_2024: "dca_class_2024",
_2025: "dca_class_2025",
_2026: "dca_class_2026",
};
/// Generic wrapper for DCA year class data
@@ -45,6 +47,7 @@ pub struct ByDcaClass<T> {
pub _2023: T,
pub _2024: T,
pub _2025: T,
pub _2026: T,
}
impl<T> ByDcaClass<T> {
@@ -66,6 +69,7 @@ impl<T> ByDcaClass<T> {
_2023: create(n._2023, y._2023, Self::dateindex(y._2023)),
_2024: create(n._2024, y._2024, Self::dateindex(y._2024)),
_2025: create(n._2025, y._2025, Self::dateindex(y._2025)),
_2026: create(n._2026, y._2026, Self::dateindex(y._2026)),
}
}
@@ -87,6 +91,7 @@ impl<T> ByDcaClass<T> {
_2023: create(n._2023, y._2023, Self::dateindex(y._2023))?,
_2024: create(n._2024, y._2024, Self::dateindex(y._2024))?,
_2025: create(n._2025, y._2025, Self::dateindex(y._2025))?,
_2026: create(n._2026, y._2026, Self::dateindex(y._2026))?,
})
}
@@ -107,6 +112,7 @@ impl<T> ByDcaClass<T> {
&self._2023,
&self._2024,
&self._2025,
&self._2026,
]
.into_iter()
}
@@ -124,6 +130,7 @@ impl<T> ByDcaClass<T> {
&mut self._2023,
&mut self._2024,
&mut self._2025,
&mut self._2026,
]
.into_iter()
}
@@ -142,11 +149,12 @@ impl<T> ByDcaClass<T> {
(&mut self._2023, Self::dateindex(y._2023)),
(&mut self._2024, Self::dateindex(y._2024)),
(&mut self._2025, Self::dateindex(y._2025)),
(&mut self._2026, Self::dateindex(y._2026)),
]
.into_iter()
}
pub fn dateindexes() -> [DateIndex; 11] {
pub fn dateindexes() -> [DateIndex; 12] {
let y = DCA_CLASS_YEARS;
[
Self::dateindex(y._2015),
@@ -160,6 +168,7 @@ impl<T> ByDcaClass<T> {
Self::dateindex(y._2023),
Self::dateindex(y._2024),
Self::dateindex(y._2025),
Self::dateindex(y._2026),
]
}
@@ -176,6 +185,7 @@ impl<T> ByDcaClass<T> {
_2023: (self._2023, other._2023),
_2024: (self._2024, other._2024),
_2025: (self._2025, other._2025),
_2026: (self._2026, other._2026),
}
}
@@ -192,6 +202,7 @@ impl<T> ByDcaClass<T> {
_2023: (&self._2023, &other._2023),
_2024: (&self._2024, &other._2024),
_2025: (&self._2025, &other._2025),
_2026: (&self._2026, &other._2026),
}
}
@@ -208,6 +219,7 @@ impl<T> ByDcaClass<T> {
_2023: f(self._2023),
_2024: f(self._2024),
_2025: f(self._2025),
_2026: f(self._2026),
}
}
}

View File

@@ -102,6 +102,9 @@ impl Vecs {
// Step 7: Aggregate to daily OHLC
self.compute_daily_ohlc(indexes, starting_indexes, exit)?;
// Step 7b: Compute close-only and mid-price daily OHLC
self.compute_close_and_mid_ohlc(indexes, price_cents, starting_indexes, exit)?;
// Step 8: Compute Phase Oracle V2 (round USD template matching)
// 8a: Per-block 200-bin histograms (uses ALL outputs, not pair-filtered)
self.compute_phase_v2_histograms(indexer, indexes, starting_indexes, exit)?;
@@ -1120,6 +1123,143 @@ impl Vecs {
Ok(())
}
/// Compute daily OHLC from height close only and mid price ((open+close)/2)
fn compute_close_and_mid_ohlc(
&mut self,
indexes: &indexes::Vecs,
price_cents: &cents::Vecs,
starting_indexes: &ComputeIndexes,
exit: &Exit,
) -> Result<()> {
let last_dateindex = DateIndex::from(indexes.dateindex.date.len());
let start_dateindex = starting_indexes
.dateindex
.min(DateIndex::from(self.close_ohlc_cents.len()))
.min(DateIndex::from(self.mid_ohlc_cents.len()));
if start_dateindex >= last_dateindex {
return Ok(());
}
let last_height = Height::from(price_cents.ohlc.height.len());
let mut close_iter = price_cents.split.height.close.iter();
let mut open_iter = price_cents.split.height.open.iter();
let mut dateindex_to_first_height_iter = indexes.dateindex.first_height.iter();
let mut height_count_iter = indexes.dateindex.height_count.iter();
for dateindex in start_dateindex.to_usize()..last_dateindex.to_usize() {
let dateindex = DateIndex::from(dateindex);
let first_height = dateindex_to_first_height_iter.get_unwrap(dateindex);
let count = height_count_iter.get_unwrap(dateindex);
if *count == 0 || first_height >= last_height {
continue;
}
let count = *count as usize;
// Close-only OHLC
let mut close_open = None;
let mut close_high = Cents::from(0i64);
let mut close_low = Cents::from(i64::MAX);
let mut close_close = Cents::from(0i64);
// Mid-price OHLC
let mut mid_open = None;
let mut mid_high = Cents::from(0i64);
let mut mid_low = Cents::from(i64::MAX);
let mut mid_close = Cents::from(0i64);
for i in 0..count {
let height = first_height + Height::from(i);
if height >= last_height {
break;
}
// Get close price for this height
if let Some(close_price) = close_iter.get(height) {
let close_cents = Cents::from(*close_price);
// Close-only OHLC
if close_open.is_none() {
close_open = Some(close_cents);
}
if close_cents > close_high {
close_high = close_cents;
}
if close_cents < close_low {
close_low = close_cents;
}
close_close = close_cents;
// Mid-price OHLC
if let Some(open_price) = open_iter.get(height) {
let open_cents = Cents::from(*open_price);
let mid_cents =
Cents::from((i64::from(open_cents) + i64::from(close_cents)) / 2);
if mid_open.is_none() {
mid_open = Some(mid_cents);
}
if mid_cents > mid_high {
mid_high = mid_cents;
}
if mid_cents < mid_low {
mid_low = mid_cents;
}
mid_close = mid_cents;
}
}
}
// Build close-only OHLC
let close_ohlc = if let Some(open_price) = close_open {
OHLCCents {
open: Open::new(open_price),
high: High::new(close_high),
low: Low::new(close_low),
close: Close::new(close_close),
}
} else if dateindex > DateIndex::from(0usize) {
self.close_ohlc_cents
.iter()?
.get(dateindex.decremented().unwrap())
.unwrap_or_default()
} else {
OHLCCents::default()
};
// Build mid-price OHLC
let mid_ohlc = if let Some(open_price) = mid_open {
OHLCCents {
open: Open::new(open_price),
high: High::new(mid_high),
low: Low::new(mid_low),
close: Close::new(mid_close),
}
} else if dateindex > DateIndex::from(0usize) {
self.mid_ohlc_cents
.iter()?
.get(dateindex.decremented().unwrap())
.unwrap_or_default()
} else {
OHLCCents::default()
};
self.close_ohlc_cents.truncate_push(dateindex, close_ohlc)?;
self.mid_ohlc_cents.truncate_push(dateindex, mid_ohlc)?;
}
// Write daily data
{
let _lock = exit.lock();
self.close_ohlc_cents.write()?;
self.mid_ohlc_cents.write()?;
}
Ok(())
}
/// Compute Phase Oracle V2 - Step 1: Per-block 200-bin phase histograms
///
/// Uses ALL outputs (like Python test), filtered only by sats range (1k-100k BTC).

View File

@@ -46,6 +46,24 @@ impl Vecs {
|di: DateIndex, iter| iter.get(di).map(|o: OHLCCents| OHLCDollars::from(o)),
);
// Daily OHLC from height close only
let close_ohlc_cents = BytesVec::forced_import(db, "close_ohlc_cents", version)?;
let close_ohlc_dollars = LazyVecFrom1::init(
"close_ohlc_dollars",
version,
close_ohlc_cents.boxed_clone(),
|di: DateIndex, iter| iter.get(di).map(|o: OHLCCents| OHLCDollars::from(o)),
);
// Daily OHLC from height mid price ((open+close)/2)
let mid_ohlc_cents = BytesVec::forced_import(db, "mid_ohlc_cents", version)?;
let mid_ohlc_dollars = LazyVecFrom1::init(
"mid_ohlc_dollars",
version,
mid_ohlc_cents.boxed_clone(),
|di: DateIndex, iter| iter.get(di).map(|o: OHLCCents| OHLCDollars::from(o)),
);
// Phase Oracle V2 (round USD template matching)
// v3: Peak prices use 100 bins (downsampled from 200)
let phase_v2_version = version + Version::new(3);
@@ -111,6 +129,10 @@ impl Vecs {
ohlc_cents,
ohlc_dollars,
tx_count,
close_ohlc_cents,
close_ohlc_dollars,
mid_ohlc_cents,
mid_ohlc_dollars,
phase_v2_histogram,
phase_v2_price_cents,
phase_v2_peak_price_cents,

View File

@@ -56,6 +56,20 @@ pub struct Vecs {
/// Number of qualifying transactions per day (for confidence)
pub tx_count: PcoVec<DateIndex, StoredU32>,
// ========== Daily OHLC from height close only ==========
/// Daily OHLC computed from height close prices only
pub close_ohlc_cents: BytesVec<DateIndex, OHLCCents>,
/// Daily OHLC from close in dollars (lazy conversion)
pub close_ohlc_dollars: LazyVecFrom1<DateIndex, OHLCDollars, DateIndex, OHLCCents>,
// ========== Daily OHLC from height mid price (open+close)/2 ==========
/// Daily OHLC computed from height mid prices ((open+close)/2)
pub mid_ohlc_cents: BytesVec<DateIndex, OHLCCents>,
/// Daily OHLC from mid in dollars (lazy conversion)
pub mid_ohlc_dollars: LazyVecFrom1<DateIndex, OHLCDollars, DateIndex, OHLCCents>,
// ========== Phase Oracle V2 (round USD template matching) ==========
/// Per-block 200-bin phase histogram
pub phase_v2_histogram: BytesVec<Height, OracleBinsV2>,

File diff suppressed because it is too large Load Diff

View File

@@ -33,6 +33,18 @@ impl Vecs {
Ok(())
})?;
self.received_sum
.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_sum_from_indexes(
starting_indexes.height,
&indexer.vecs.transactions.first_txindex,
&indexes.height.txindex_count,
&fees_vecs.output_value,
exit,
)?;
Ok(())
})?;
self.annualized_volume.compute_sats(|v| {
v.compute_sum(
starting_indexes.dateindex,

View File

@@ -23,6 +23,13 @@ impl Vecs {
indexes,
price,
)?,
received_sum: ValueFromHeightSum::forced_import(
db,
"received_sum",
version,
indexes,
price,
)?,
annualized_volume: ValueFromDateLast::forced_import(
db,
"annualized_volume",

View File

@@ -7,6 +7,7 @@ use crate::internal::{ComputedFromDateLast, ValueFromHeightSum, ValueFromDateLas
#[derive(Clone, Traversable)]
pub struct Vecs {
pub sent_sum: ValueFromHeightSum,
pub received_sum: ValueFromHeightSum,
pub annualized_volume: ValueFromDateLast,
pub tx_per_sec: ComputedFromDateLast<StoredF32>,
pub outputs_per_sec: ComputedFromDateLast<StoredF32>,