mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 14:49:58 -07:00
global: snapshot
This commit is contained in:
@@ -24,8 +24,6 @@ pub const DB_NAME: &str = "blocks";
|
||||
|
||||
pub(crate) const TARGET_BLOCKS_PER_DAY_F64: f64 = 144.0;
|
||||
pub(crate) const TARGET_BLOCKS_PER_DAY_F32: f32 = 144.0;
|
||||
pub(crate) const TARGET_BLOCKS_PER_MINUTE1: u64 = 0;
|
||||
pub(crate) const TARGET_BLOCKS_PER_MINUTE5: u64 = 0;
|
||||
pub(crate) const TARGET_BLOCKS_PER_MINUTE10: u64 = 1;
|
||||
pub(crate) const TARGET_BLOCKS_PER_MINUTE30: u64 = 3;
|
||||
pub(crate) const TARGET_BLOCKS_PER_HOUR1: u64 = 6;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Date, Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4, Minute1,
|
||||
Minute10, Minute30, Minute5, Month1, Month3, Month6, Timestamp, Week1, Year1, Year10,
|
||||
Date, Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4,
|
||||
Minute10, Minute30, Month1, Month3, Month6, Timestamp, Week1, Year1, Year10,
|
||||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::{EagerVec, Exit, LazyVecFrom1, PcoVec, Rw, StorageMode};
|
||||
@@ -19,7 +19,7 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
|
||||
/// Per-period timestamp indexes.
|
||||
///
|
||||
/// Time-based periods (minute1–year10) are lazy: `idx.to_timestamp()` is a pure
|
||||
/// Time-based periods (minute10–year10) are lazy: `idx.to_timestamp()` is a pure
|
||||
/// function of the index, so no storage or decompression is needed.
|
||||
/// Epoch-based periods (halvingepoch, difficultyepoch) are eager: their timestamps
|
||||
/// come from block data via `compute_indirect`.
|
||||
@@ -28,8 +28,6 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub struct TimestampIndexes<M: StorageMode = Rw>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
LazyVecFrom1<Minute1, Timestamp, Minute1, Height>,
|
||||
LazyVecFrom1<Minute5, Timestamp, Minute5, Height>,
|
||||
LazyVecFrom1<Minute10, Timestamp, Minute10, Height>,
|
||||
LazyVecFrom1<Minute30, Timestamp, Minute30, Height>,
|
||||
LazyVecFrom1<Hour1, Timestamp, Hour1, Height>,
|
||||
|
||||
@@ -867,6 +867,30 @@ impl RealizedBase {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.lower_price_band.usd.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&self.realized_price.usd.height,
|
||||
&self.investor_price.usd.height,
|
||||
|(i, rp, ip, ..)| {
|
||||
let rp = f64::from(rp);
|
||||
let ip = f64::from(ip);
|
||||
(i, Dollars::from(rp * rp / ip))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.upper_price_band.usd.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&self.investor_price.usd.height,
|
||||
&self.realized_price.usd.height,
|
||||
|(i, ip, rp, ..)| {
|
||||
let ip = f64::from(ip);
|
||||
let rp = f64::from(rp);
|
||||
(i, Dollars::from(ip * ip / rp))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.realized_cap_30d_delta.height.compute_rolling_change(
|
||||
starting_indexes.height,
|
||||
&blocks.count.height_1m_ago,
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, Height, Sats, StoredF32, StoredF64, Version};
|
||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||
use vecdb::{Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
|
||||
|
||||
use crate::internal::{
|
||||
ComputedFromHeightLast,
|
||||
ComputedFromHeightLast, LazyFromHeightLast,
|
||||
NegPercentageDollarsF32, PercentageDollarsF32, PercentageSatsF64,
|
||||
StoredF32Identity,
|
||||
};
|
||||
|
||||
use crate::distribution::metrics::{ImportConfig, RealizedBase, UnrealizedBase};
|
||||
@@ -24,7 +25,7 @@ pub struct RelativeBase<M: StorageMode = Rw> {
|
||||
pub unrealized_loss_rel_to_market_cap: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub neg_unrealized_loss_rel_to_market_cap: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub net_unrealized_pnl_rel_to_market_cap: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub nupl: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub nupl: LazyFromHeightLast<StoredF32, StoredF32>,
|
||||
|
||||
// === Invested Capital in Profit/Loss as % of Realized Cap ===
|
||||
pub invested_capital_in_profit_pct: ComputedFromHeightLast<StoredF32, M>,
|
||||
@@ -36,6 +37,17 @@ impl RelativeBase {
|
||||
let v1 = Version::ONE;
|
||||
let v2 = Version::new(2);
|
||||
|
||||
let net_unrealized_pnl_rel_to_market_cap = ComputedFromHeightLast::forced_import(
|
||||
cfg.db, &cfg.name("net_unrealized_pnl_rel_to_market_cap"), cfg.version + v2, cfg.indexes,
|
||||
)?;
|
||||
|
||||
let nupl = LazyFromHeightLast::from_computed::<StoredF32Identity>(
|
||||
&cfg.name("nupl"),
|
||||
cfg.version + v2,
|
||||
net_unrealized_pnl_rel_to_market_cap.height.read_only_boxed_clone(),
|
||||
&net_unrealized_pnl_rel_to_market_cap,
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
supply_in_profit_rel_to_own_supply: ComputedFromHeightLast::forced_import(
|
||||
cfg.db, &cfg.name("supply_in_profit_rel_to_own_supply"), cfg.version + v1, cfg.indexes,
|
||||
@@ -52,12 +64,8 @@ impl RelativeBase {
|
||||
neg_unrealized_loss_rel_to_market_cap: ComputedFromHeightLast::forced_import(
|
||||
cfg.db, &cfg.name("neg_unrealized_loss_rel_to_market_cap"), cfg.version + v2, cfg.indexes,
|
||||
)?,
|
||||
net_unrealized_pnl_rel_to_market_cap: ComputedFromHeightLast::forced_import(
|
||||
cfg.db, &cfg.name("net_unrealized_pnl_rel_to_market_cap"), cfg.version + v2, cfg.indexes,
|
||||
)?,
|
||||
nupl: ComputedFromHeightLast::forced_import(
|
||||
cfg.db, &cfg.name("nupl"), cfg.version + v2, cfg.indexes,
|
||||
)?,
|
||||
net_unrealized_pnl_rel_to_market_cap,
|
||||
nupl,
|
||||
invested_capital_in_profit_pct: ComputedFromHeightLast::forced_import(
|
||||
cfg.db, &cfg.name("invested_capital_in_profit_pct"), cfg.version, cfg.indexes,
|
||||
)?,
|
||||
@@ -100,10 +108,6 @@ impl RelativeBase {
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.net_unrealized_pnl.height, market_cap, exit,
|
||||
)?;
|
||||
self.nupl
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.net_unrealized_pnl.height, market_cap, exit,
|
||||
)?;
|
||||
self.invested_capital_in_profit_pct
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.invested_capital_in_profit.height, &realized.realized_cap.height, exit,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Day1, Day3, Year10, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4,
|
||||
Minute1, Minute10, Minute30, Minute5, Month1, Month3, Month6, StoredU64, Version, Week1,
|
||||
Minute10, Minute30, Month1, Month3, Month6, StoredU64, Version, Week1,
|
||||
Year1,
|
||||
};
|
||||
use vecdb::{Database, EagerVec, ImportableVec, PcoVec, Rw, StorageMode};
|
||||
@@ -11,8 +11,6 @@ use brk_error::Result;
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub identity: M::Stored<EagerVec<PcoVec<Height, Height>>>,
|
||||
pub minute1: M::Stored<EagerVec<PcoVec<Height, Minute1>>>,
|
||||
pub minute5: M::Stored<EagerVec<PcoVec<Height, Minute5>>>,
|
||||
pub minute10: M::Stored<EagerVec<PcoVec<Height, Minute10>>>,
|
||||
pub minute30: M::Stored<EagerVec<PcoVec<Height, Minute30>>>,
|
||||
pub hour1: M::Stored<EagerVec<PcoVec<Height, Hour1>>>,
|
||||
@@ -35,8 +33,6 @@ impl Vecs {
|
||||
pub(crate) fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
identity: EagerVec::forced_import(db, "height", version)?,
|
||||
minute1: EagerVec::forced_import(db, "minute1", version)?,
|
||||
minute5: EagerVec::forced_import(db, "minute5", version)?,
|
||||
minute10: EagerVec::forced_import(db, "minute10", version)?,
|
||||
minute30: EagerVec::forced_import(db, "minute30", version)?,
|
||||
hour1: EagerVec::forced_import(db, "hour1", version)?,
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Minute1, Version};
|
||||
use vecdb::{Database, EagerVec, ImportableVec, PcoVec, Rw, StorageMode};
|
||||
|
||||
use brk_error::Result;
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub identity: M::Stored<EagerVec<PcoVec<Minute1, Minute1>>>,
|
||||
pub first_height: M::Stored<EagerVec<PcoVec<Minute1, Height>>>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
identity: EagerVec::forced_import(db, "minute1", version)?,
|
||||
first_height: EagerVec::forced_import(db, "minute1_first_height", version)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Minute5, Version};
|
||||
use vecdb::{Database, EagerVec, ImportableVec, PcoVec, Rw, StorageMode};
|
||||
|
||||
use brk_error::Result;
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub identity: M::Stored<EagerVec<PcoVec<Minute5, Minute5>>>,
|
||||
pub first_height: M::Stored<EagerVec<PcoVec<Minute5, Height>>>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
identity: EagerVec::forced_import(db, "minute5", version)?,
|
||||
first_height: EagerVec::forced_import(db, "minute5_first_height", version)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,8 @@ mod height;
|
||||
mod hour1;
|
||||
mod hour12;
|
||||
mod hour4;
|
||||
mod minute1;
|
||||
mod minute10;
|
||||
mod minute30;
|
||||
mod minute5;
|
||||
mod month1;
|
||||
mod month3;
|
||||
mod month6;
|
||||
@@ -27,7 +25,7 @@ use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Date, Day1, Day3, Hour1, Hour4, Hour12, Indexes, Minute1, Minute5, Minute10, Minute30, Month1,
|
||||
Date, Day1, Day3, Hour1, Hour4, Hour12, Indexes, Minute10, Minute30, Month1,
|
||||
Month3, Month6, Version, Week1, Year1, Year10,
|
||||
};
|
||||
use vecdb::{Database, Exit, PAGE_SIZE, ReadableVec, Rw, StorageMode};
|
||||
@@ -44,8 +42,6 @@ pub use height::Vecs as HeightVecs;
|
||||
pub use hour1::Vecs as Hour1Vecs;
|
||||
pub use hour4::Vecs as Hour4Vecs;
|
||||
pub use hour12::Vecs as Hour12Vecs;
|
||||
pub use minute1::Vecs as Minute1Vecs;
|
||||
pub use minute5::Vecs as Minute5Vecs;
|
||||
pub use minute10::Vecs as Minute10Vecs;
|
||||
pub use minute30::Vecs as Minute30Vecs;
|
||||
pub use month1::Vecs as Month1Vecs;
|
||||
@@ -68,8 +64,6 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub height: HeightVecs<M>,
|
||||
pub difficultyepoch: DifficultyEpochVecs<M>,
|
||||
pub halvingepoch: HalvingEpochVecs<M>,
|
||||
pub minute1: Minute1Vecs<M>,
|
||||
pub minute5: Minute5Vecs<M>,
|
||||
pub minute10: Minute10Vecs<M>,
|
||||
pub minute30: Minute30Vecs<M>,
|
||||
pub hour1: Hour1Vecs<M>,
|
||||
@@ -104,8 +98,6 @@ impl Vecs {
|
||||
height: HeightVecs::forced_import(&db, version)?,
|
||||
difficultyepoch: DifficultyEpochVecs::forced_import(&db, version)?,
|
||||
halvingepoch: HalvingEpochVecs::forced_import(&db, version)?,
|
||||
minute1: Minute1Vecs::forced_import(&db, version)?,
|
||||
minute5: Minute5Vecs::forced_import(&db, version)?,
|
||||
minute10: Minute10Vecs::forced_import(&db, version)?,
|
||||
minute30: Minute30Vecs::forced_import(&db, version)?,
|
||||
hour1: Hour1Vecs::forced_import(&db, version)?,
|
||||
@@ -190,22 +182,6 @@ impl Vecs {
|
||||
|
||||
// --- Timestamp-based height → period mappings ---
|
||||
|
||||
// Minute1
|
||||
self.height.minute1.compute_transform(
|
||||
starting_indexes.height,
|
||||
&blocks_time.timestamp_monotonic,
|
||||
|(h, ts, _)| (h, Minute1::from_timestamp(ts)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Minute5
|
||||
self.height.minute5.compute_transform(
|
||||
starting_indexes.height,
|
||||
&blocks_time.timestamp_monotonic,
|
||||
|(h, ts, _)| (h, Minute5::from_timestamp(ts)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Minute10
|
||||
self.height.minute10.compute_transform(
|
||||
starting_indexes.height,
|
||||
@@ -376,16 +352,6 @@ impl Vecs {
|
||||
|
||||
// --- Starting values from height → period mappings ---
|
||||
|
||||
let starting_minute1 = self
|
||||
.height
|
||||
.minute1
|
||||
.collect_one(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
let starting_minute5 = self
|
||||
.height
|
||||
.minute5
|
||||
.collect_one(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
let starting_minute10 = self
|
||||
.height
|
||||
.minute10
|
||||
@@ -449,30 +415,6 @@ impl Vecs {
|
||||
|
||||
// --- Compute period-level vecs (first_height + identity) ---
|
||||
|
||||
// Minute1
|
||||
self.minute1.first_height.compute_first_per_index(
|
||||
starting_indexes.height,
|
||||
&self.height.minute1,
|
||||
exit,
|
||||
)?;
|
||||
self.minute1.identity.compute_from_index(
|
||||
starting_minute1,
|
||||
&self.minute1.first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Minute5
|
||||
self.minute5.first_height.compute_first_per_index(
|
||||
starting_indexes.height,
|
||||
&self.height.minute5,
|
||||
exit,
|
||||
)?;
|
||||
self.minute5.identity.compute_from_index(
|
||||
starting_minute5,
|
||||
&self.minute5.first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Minute10
|
||||
self.minute10.first_height.compute_first_per_index(
|
||||
starting_indexes.height,
|
||||
@@ -669,8 +611,6 @@ impl Vecs {
|
||||
|
||||
Ok(ComputeIndexes::new(
|
||||
starting_indexes,
|
||||
starting_minute1,
|
||||
starting_minute5,
|
||||
starting_minute10,
|
||||
starting_minute30,
|
||||
starting_hour1,
|
||||
|
||||
@@ -7,7 +7,7 @@ use brk_error::Result;
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour4, Hour12, Minute1, Minute5,
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour4, Hour12,
|
||||
Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
@@ -18,7 +18,7 @@ use vecdb::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ComputeIndexes, indexes, indexes_from,
|
||||
ComputeIndexes, indexes, indexes_apply, indexes_from,
|
||||
internal::{ComputedVecValue, Indexes, NumericValue},
|
||||
};
|
||||
|
||||
@@ -27,8 +27,6 @@ use crate::{
|
||||
pub struct EagerIndexes<T, M: StorageMode = Rw>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
<M as StorageMode>::Stored<EagerVec<PcoVec<Minute1, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<PcoVec<Minute5, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<PcoVec<Minute10, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<PcoVec<Minute30, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<PcoVec<Hour1, T>>>,
|
||||
@@ -86,23 +84,7 @@ where
|
||||
};
|
||||
}
|
||||
|
||||
period!(minute1);
|
||||
period!(minute5);
|
||||
period!(minute10);
|
||||
period!(minute30);
|
||||
period!(hour1);
|
||||
period!(hour4);
|
||||
period!(hour12);
|
||||
period!(day1);
|
||||
period!(day3);
|
||||
period!(week1);
|
||||
period!(month1);
|
||||
period!(month3);
|
||||
period!(month6);
|
||||
period!(year1);
|
||||
period!(year10);
|
||||
period!(halvingepoch);
|
||||
period!(difficultyepoch);
|
||||
indexes_apply!(period);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -131,23 +113,7 @@ where
|
||||
};
|
||||
}
|
||||
|
||||
period!(minute1);
|
||||
period!(minute5);
|
||||
period!(minute10);
|
||||
period!(minute30);
|
||||
period!(hour1);
|
||||
period!(hour4);
|
||||
period!(hour12);
|
||||
period!(day1);
|
||||
period!(day3);
|
||||
period!(week1);
|
||||
period!(month1);
|
||||
period!(month3);
|
||||
period!(month6);
|
||||
period!(year1);
|
||||
period!(year10);
|
||||
period!(halvingepoch);
|
||||
period!(difficultyepoch);
|
||||
indexes_apply!(period);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -176,23 +142,7 @@ where
|
||||
};
|
||||
}
|
||||
|
||||
period!(minute1);
|
||||
period!(minute5);
|
||||
period!(minute10);
|
||||
period!(minute30);
|
||||
period!(hour1);
|
||||
period!(hour4);
|
||||
period!(hour12);
|
||||
period!(day1);
|
||||
period!(day3);
|
||||
period!(week1);
|
||||
period!(month1);
|
||||
period!(month3);
|
||||
period!(month6);
|
||||
period!(year1);
|
||||
period!(year10);
|
||||
period!(halvingepoch);
|
||||
period!(difficultyepoch);
|
||||
indexes_apply!(period);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4, Minute1, Minute10,
|
||||
Minute30, Minute5, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4,
|
||||
Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
@@ -18,8 +18,6 @@ where
|
||||
T: VecValue + Formattable + Serialize + JsonSchema,
|
||||
{
|
||||
pub height: LazyVecFrom1<Height, T, Height, Height>,
|
||||
pub minute1: LazyVecFrom1<Minute1, T, Minute1, Minute1>,
|
||||
pub minute5: LazyVecFrom1<Minute5, T, Minute5, Minute5>,
|
||||
pub minute10: LazyVecFrom1<Minute10, T, Minute10, Minute10>,
|
||||
pub minute30: LazyVecFrom1<Minute30, T, Minute30, Minute30>,
|
||||
pub hour1: LazyVecFrom1<Hour1, T, Hour1, Hour1>,
|
||||
@@ -42,8 +40,6 @@ impl<T: VecValue + Formattable + Serialize + JsonSchema> ConstantVecs<T> {
|
||||
pub(crate) fn new<F>(name: &str, version: Version, indexes: &indexes::Vecs) -> Self
|
||||
where
|
||||
F: UnaryTransform<Height, T>
|
||||
+ UnaryTransform<Minute1, T>
|
||||
+ UnaryTransform<Minute5, T>
|
||||
+ UnaryTransform<Minute10, T>
|
||||
+ UnaryTransform<Minute30, T>
|
||||
+ UnaryTransform<Hour1, T>
|
||||
@@ -76,8 +72,6 @@ impl<T: VecValue + Formattable + Serialize + JsonSchema> ConstantVecs<T> {
|
||||
version,
|
||||
indexes.height.identity.read_only_boxed_clone(),
|
||||
),
|
||||
minute1: period!(minute1, Minute1),
|
||||
minute5: period!(minute5, Minute5),
|
||||
minute10: period!(minute10, Minute10),
|
||||
minute30: period!(minute30, Minute30),
|
||||
hour1: period!(hour1, Hour1),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Day1, Day3, DifficultyEpoch, FromCoarserIndex, HalvingEpoch, Height, Hour1, Hour4, Hour12,
|
||||
Minute1, Minute5, Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use schemars::JsonSchema;
|
||||
@@ -21,8 +21,6 @@ use crate::{
|
||||
pub struct ComputedHeightDerivedLast<T>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
LazyAggVec<Minute1, Option<T>, Height, Height, T>,
|
||||
LazyAggVec<Minute5, Option<T>, Height, Height, T>,
|
||||
LazyAggVec<Minute10, Option<T>, Height, Height, T>,
|
||||
LazyAggVec<Minute30, Option<T>, Height, Height, T>,
|
||||
LazyAggVec<Hour1, Option<T>, Height, Height, T>,
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::marker::PhantomData;
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour4, Hour12, Minute1, Minute5,
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour4, Hour12,
|
||||
Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
@@ -60,8 +60,6 @@ where
|
||||
pub struct LazyHeightDerivedLast<T, S1T = T>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
LazyTransformLast<Minute1, Option<T>, Option<S1T>>,
|
||||
LazyTransformLast<Minute5, Option<T>, Option<S1T>>,
|
||||
LazyTransformLast<Minute10, Option<T>, Option<S1T>>,
|
||||
LazyTransformLast<Minute30, Option<T>, Option<S1T>>,
|
||||
LazyTransformLast<Hour1, Option<T>, Option<S1T>>,
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
//! Base generic struct with 17 type parameters — one per time period/epoch index.
|
||||
//! Base generic struct with 15 type parameters — one per time period/epoch index.
|
||||
//!
|
||||
//! Foundation for all per-index types. Replaces the repetitive 17-field pattern
|
||||
//! Foundation for all per-index types. Replaces the repetitive 15-field pattern
|
||||
//! found throughout height_derived types.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct Indexes<M1, M5, M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE, DE> {
|
||||
pub minute1: M1,
|
||||
pub minute5: M5,
|
||||
pub struct Indexes<M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE, DE> {
|
||||
pub minute10: M10,
|
||||
pub minute30: M30,
|
||||
pub hour1: H1,
|
||||
@@ -38,8 +36,6 @@ pub struct Indexes<M1, M5, M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1,
|
||||
macro_rules! indexes_from {
|
||||
($period:ident, $epoch:ident) => {
|
||||
$crate::internal::Indexes {
|
||||
minute1: $period!(minute1),
|
||||
minute5: $period!(minute5),
|
||||
minute10: $period!(minute10),
|
||||
minute30: $period!(minute30),
|
||||
hour1: $period!(hour1),
|
||||
@@ -63,29 +59,28 @@ macro_rules! indexes_from {
|
||||
};
|
||||
}
|
||||
|
||||
/// Helper macro to apply a function/macro to each field of an `Indexes` value.
|
||||
/// Imperative counterpart to `indexes_from!` — calls `$period!(field)` for each
|
||||
/// period field and `$epoch!(field)` for each epoch field.
|
||||
#[macro_export]
|
||||
macro_rules! indexes_map {
|
||||
($indexes:expr, |$field:ident| $body:expr) => {{
|
||||
let src = $indexes;
|
||||
$crate::internal::Indexes {
|
||||
minute1: { let $field = src.minute1; $body },
|
||||
minute5: { let $field = src.minute5; $body },
|
||||
minute10: { let $field = src.minute10; $body },
|
||||
minute30: { let $field = src.minute30; $body },
|
||||
hour1: { let $field = src.hour1; $body },
|
||||
hour4: { let $field = src.hour4; $body },
|
||||
hour12: { let $field = src.hour12; $body },
|
||||
day1: { let $field = src.day1; $body },
|
||||
day3: { let $field = src.day3; $body },
|
||||
week1: { let $field = src.week1; $body },
|
||||
month1: { let $field = src.month1; $body },
|
||||
month3: { let $field = src.month3; $body },
|
||||
month6: { let $field = src.month6; $body },
|
||||
year1: { let $field = src.year1; $body },
|
||||
year10: { let $field = src.year10; $body },
|
||||
halvingepoch: { let $field = src.halvingepoch; $body },
|
||||
difficultyepoch: { let $field = src.difficultyepoch; $body },
|
||||
}
|
||||
}};
|
||||
macro_rules! indexes_apply {
|
||||
($period:ident, $epoch:ident) => {
|
||||
$period!(minute10);
|
||||
$period!(minute30);
|
||||
$period!(hour1);
|
||||
$period!(hour4);
|
||||
$period!(hour12);
|
||||
$period!(day1);
|
||||
$period!(day3);
|
||||
$period!(week1);
|
||||
$period!(month1);
|
||||
$period!(month3);
|
||||
$period!(month6);
|
||||
$period!(year1);
|
||||
$period!(year10);
|
||||
$epoch!(halvingepoch);
|
||||
$epoch!(difficultyepoch);
|
||||
};
|
||||
($m:ident) => {
|
||||
$crate::indexes_apply!($m, $m)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Hour1, Hour4, Hour12, Minute1, Minute5, Minute10,
|
||||
Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Hour1, Hour4, Hour12,
|
||||
Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use schemars::JsonSchema;
|
||||
@@ -22,8 +22,6 @@ use crate::{
|
||||
pub struct LazyEagerIndexes<T, S>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
LazyVecFrom1<Minute1, T, Minute1, S>,
|
||||
LazyVecFrom1<Minute5, T, Minute5, S>,
|
||||
LazyVecFrom1<Minute10, T, Minute10, S>,
|
||||
LazyVecFrom1<Minute30, T, Minute30, S>,
|
||||
LazyVecFrom1<Hour1, T, Hour1, S>,
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use brk_types::{
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4, Minute1, Minute10,
|
||||
Minute30, Minute5, Month1, Month3, Month6, StoredU64, Week1, Year1, Year10,
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4,
|
||||
Minute10, Minute30, Month1, Month3, Month6, StoredU64, Week1, Year1, Year10,
|
||||
};
|
||||
use vecdb::UnaryTransform;
|
||||
|
||||
use crate::blocks::{
|
||||
TARGET_BLOCKS_PER_DAY, TARGET_BLOCKS_PER_DAY3, TARGET_BLOCKS_PER_DECADE,
|
||||
TARGET_BLOCKS_PER_HALVING, TARGET_BLOCKS_PER_HOUR1, TARGET_BLOCKS_PER_HOUR12,
|
||||
TARGET_BLOCKS_PER_HOUR4, TARGET_BLOCKS_PER_MINUTE1, TARGET_BLOCKS_PER_MINUTE10,
|
||||
TARGET_BLOCKS_PER_MINUTE30, TARGET_BLOCKS_PER_MINUTE5, TARGET_BLOCKS_PER_MONTH,
|
||||
TARGET_BLOCKS_PER_HOUR4, TARGET_BLOCKS_PER_MINUTE10,
|
||||
TARGET_BLOCKS_PER_MINUTE30, TARGET_BLOCKS_PER_MONTH,
|
||||
TARGET_BLOCKS_PER_QUARTER, TARGET_BLOCKS_PER_SEMESTER, TARGET_BLOCKS_PER_WEEK,
|
||||
TARGET_BLOCKS_PER_YEAR,
|
||||
};
|
||||
@@ -22,20 +22,6 @@ impl UnaryTransform<Height, StoredU64> for BlockCountTarget {
|
||||
}
|
||||
}
|
||||
|
||||
impl UnaryTransform<Minute1, StoredU64> for BlockCountTarget {
|
||||
#[inline(always)]
|
||||
fn apply(_: Minute1) -> StoredU64 {
|
||||
StoredU64::from(TARGET_BLOCKS_PER_MINUTE1)
|
||||
}
|
||||
}
|
||||
|
||||
impl UnaryTransform<Minute5, StoredU64> for BlockCountTarget {
|
||||
#[inline(always)]
|
||||
fn apply(_: Minute5) -> StoredU64 {
|
||||
StoredU64::from(TARGET_BLOCKS_PER_MINUTE5)
|
||||
}
|
||||
}
|
||||
|
||||
impl UnaryTransform<Minute10, StoredU64> for BlockCountTarget {
|
||||
#[inline(always)]
|
||||
fn apply(_: Minute10) -> StoredU64 {
|
||||
|
||||
@@ -3,7 +3,7 @@ use brk_types::StoredU16;
|
||||
use vecdb::{Exit, ReadableVec, VecIndex};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{ComputeIndexes, prices};
|
||||
use crate::{ComputeIndexes, prices, traits::ComputeDrawdown};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn compute(
|
||||
@@ -63,6 +63,13 @@ impl Vecs {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.price_drawdown.height.compute_drawdown(
|
||||
starting_indexes.height,
|
||||
&prices.price.usd.height,
|
||||
&self.price_ath.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ impl Vecs {
|
||||
|(h, close, low, high, ..)| {
|
||||
let range = *high - *low;
|
||||
let stoch = if range == 0.0 {
|
||||
StoredF32::from(50.0)
|
||||
StoredF32::NAN
|
||||
} else {
|
||||
StoredF32::from(((*close - *low) / range * 100.0) as f32)
|
||||
};
|
||||
|
||||
@@ -72,7 +72,7 @@ pub(super) fn compute(
|
||||
.map(|((r, mn), mx)| {
|
||||
let range = mx - mn;
|
||||
if range == 0.0 {
|
||||
50.0
|
||||
f32::NAN
|
||||
} else {
|
||||
(r - mn) / range * 100.0
|
||||
}
|
||||
|
||||
@@ -26,11 +26,7 @@ pub(super) fn compute_ema(source: &[f32], period: usize) -> Vec<f32> {
|
||||
for (i, &val) in source.iter().enumerate() {
|
||||
if i < period {
|
||||
sum += val;
|
||||
if i == period - 1 {
|
||||
result.push(sum / period as f32);
|
||||
} else {
|
||||
result.push(val);
|
||||
}
|
||||
result.push(sum / (i + 1) as f32);
|
||||
} else {
|
||||
let prev = result[i - 1];
|
||||
result.push(val * k + prev * (1.0 - k));
|
||||
|
||||
@@ -102,18 +102,18 @@ impl Vecs {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Choppiness index: 100 * log10(tr_2w_sum / (price_2w_max - price_2w_min)) / log10(14)
|
||||
let log10n = 14.0f32.log10();
|
||||
self.price_2w_choppiness_index.height.compute_transform3(
|
||||
self.price_2w_choppiness_index.height.compute_transform4(
|
||||
starting_indexes.height,
|
||||
&self.price_true_range_2w_sum.height,
|
||||
&self.price_2w_max.usd.height,
|
||||
&self.price_2w_min.usd.height,
|
||||
|(h, tr_sum, max, min, ..)| {
|
||||
&blocks.count.height_2w_ago,
|
||||
|(h, tr_sum, max, min, window_start, ..)| {
|
||||
let range = *max - *min;
|
||||
let ci = if range > 0.0 {
|
||||
let n = (h.to_usize() - window_start.to_usize() + 1) as f32;
|
||||
let ci = if range > 0.0 && n > 1.0 {
|
||||
StoredF32::from(
|
||||
100.0 * (*tr_sum / range as f32).log10() / log10n,
|
||||
100.0 * (*tr_sum / range as f32).log10() / n.log10(),
|
||||
)
|
||||
} else {
|
||||
StoredF32::NAN
|
||||
|
||||
@@ -2,7 +2,7 @@ use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Cents, Close, Day1, Day3, DifficultyEpoch, HalvingEpoch, High, Hour1, Hour4, Hour12, Low,
|
||||
Minute1, Minute5, Minute10, Minute30, Month1, Month3, Month6, OHLCCents, Open, Version, Week1,
|
||||
Minute10, Minute30, Month1, Month3, Month6, OHLCCents, Open, Version, Week1,
|
||||
Year1, Year10,
|
||||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
@@ -14,7 +14,7 @@ use vecdb::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ComputeIndexes, indexes_from,
|
||||
ComputeIndexes, indexes_apply, indexes_from,
|
||||
internal::{ComputedHeightDerivedLast, EagerIndexes, Indexes},
|
||||
};
|
||||
|
||||
@@ -25,8 +25,6 @@ use crate::{
|
||||
pub struct OhlcVecs<T, M: StorageMode = Rw>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
<M as StorageMode>::Stored<EagerVec<BytesVec<Minute1, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<BytesVec<Minute5, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<BytesVec<Minute10, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<BytesVec<Minute30, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<BytesVec<Hour1, T>>>,
|
||||
@@ -132,23 +130,7 @@ impl OhlcVecs<OHLCCents> {
|
||||
};
|
||||
}
|
||||
|
||||
period!(minute1);
|
||||
period!(minute5);
|
||||
period!(minute10);
|
||||
period!(minute30);
|
||||
period!(hour1);
|
||||
period!(hour4);
|
||||
period!(hour12);
|
||||
period!(day1);
|
||||
period!(day3);
|
||||
period!(week1);
|
||||
period!(month1);
|
||||
period!(month3);
|
||||
period!(month6);
|
||||
period!(year1);
|
||||
period!(year10);
|
||||
epoch!(halvingepoch);
|
||||
epoch!(difficultyepoch);
|
||||
indexes_apply!(period, epoch);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -161,8 +143,6 @@ impl OhlcVecs<OHLCCents> {
|
||||
pub struct LazyOhlcVecs<T, S>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
LazyVecFrom1<Minute1, T, Minute1, S>,
|
||||
LazyVecFrom1<Minute5, T, Minute5, S>,
|
||||
LazyVecFrom1<Minute10, T, Minute10, S>,
|
||||
LazyVecFrom1<Minute30, T, Minute30, S>,
|
||||
LazyVecFrom1<Hour1, T, Hour1, S>,
|
||||
|
||||
Reference in New Issue
Block a user