mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: sats version of all prices
This commit is contained in:
@@ -5,7 +5,7 @@ use vecdb::Database;
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{ComputedFromHeightLast, ComputedFromDateRatio},
|
||||
internal::{ComputedFromDateRatio, PriceFromHeight},
|
||||
price,
|
||||
};
|
||||
|
||||
@@ -16,41 +16,61 @@ impl Vecs {
|
||||
indexes: &indexes::Vecs,
|
||||
price: Option<&price::Vecs>,
|
||||
) -> Result<Self> {
|
||||
macro_rules! computed_h {
|
||||
($name:expr) => {
|
||||
ComputedFromHeightLast::forced_import(db, $name, version, indexes)?
|
||||
};
|
||||
}
|
||||
let vaulted_price = PriceFromHeight::forced_import(db, "vaulted_price", version, indexes)?;
|
||||
let vaulted_price_ratio = ComputedFromDateRatio::forced_import(
|
||||
db,
|
||||
"vaulted_price",
|
||||
Some(&vaulted_price),
|
||||
version,
|
||||
indexes,
|
||||
true,
|
||||
price,
|
||||
)?;
|
||||
|
||||
// Extract price vecs before struct literal so they can be used as sources for ratios
|
||||
let vaulted_price = computed_h!("vaulted_price");
|
||||
let active_price = computed_h!("active_price");
|
||||
let true_market_mean = computed_h!("true_market_mean");
|
||||
let cointime_price = computed_h!("cointime_price");
|
||||
let active_price = PriceFromHeight::forced_import(db, "active_price", version, indexes)?;
|
||||
let active_price_ratio = ComputedFromDateRatio::forced_import(
|
||||
db,
|
||||
"active_price",
|
||||
Some(&active_price),
|
||||
version,
|
||||
indexes,
|
||||
true,
|
||||
price,
|
||||
)?;
|
||||
|
||||
macro_rules! ratio_di {
|
||||
($name:expr, $source:expr) => {
|
||||
ComputedFromDateRatio::forced_import(
|
||||
db,
|
||||
$name,
|
||||
Some($source),
|
||||
version,
|
||||
indexes,
|
||||
true,
|
||||
price,
|
||||
)?
|
||||
};
|
||||
}
|
||||
let true_market_mean =
|
||||
PriceFromHeight::forced_import(db, "true_market_mean", version, indexes)?;
|
||||
let true_market_mean_ratio = ComputedFromDateRatio::forced_import(
|
||||
db,
|
||||
"true_market_mean",
|
||||
Some(&true_market_mean),
|
||||
version,
|
||||
indexes,
|
||||
true,
|
||||
price,
|
||||
)?;
|
||||
|
||||
let cointime_price =
|
||||
PriceFromHeight::forced_import(db, "cointime_price", version, indexes)?;
|
||||
let cointime_price_ratio = ComputedFromDateRatio::forced_import(
|
||||
db,
|
||||
"cointime_price",
|
||||
Some(&cointime_price),
|
||||
version,
|
||||
indexes,
|
||||
true,
|
||||
price,
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
vaulted_price_ratio: ratio_di!("vaulted_price", &vaulted_price),
|
||||
vaulted_price,
|
||||
active_price_ratio: ratio_di!("active_price", &active_price),
|
||||
vaulted_price_ratio,
|
||||
active_price,
|
||||
true_market_mean_ratio: ratio_di!("true_market_mean", &true_market_mean),
|
||||
active_price_ratio,
|
||||
true_market_mean,
|
||||
cointime_price_ratio: ratio_di!("cointime_price", &cointime_price),
|
||||
true_market_mean_ratio,
|
||||
cointime_price,
|
||||
cointime_price_ratio,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Dollars;
|
||||
|
||||
use crate::internal::{ComputedFromHeightLast, ComputedFromDateRatio};
|
||||
use crate::internal::{ComputedFromDateRatio, PriceFromHeight};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub vaulted_price: ComputedFromHeightLast<Dollars>,
|
||||
pub vaulted_price: PriceFromHeight,
|
||||
pub vaulted_price_ratio: ComputedFromDateRatio,
|
||||
pub active_price: ComputedFromHeightLast<Dollars>,
|
||||
pub active_price: PriceFromHeight,
|
||||
pub active_price_ratio: ComputedFromDateRatio,
|
||||
pub true_market_mean: ComputedFromHeightLast<Dollars>,
|
||||
pub true_market_mean: PriceFromHeight,
|
||||
pub true_market_mean_ratio: ComputedFromDateRatio,
|
||||
pub cointime_price: ComputedFromHeightLast<Dollars>,
|
||||
pub cointime_price: PriceFromHeight,
|
||||
pub cointime_price_ratio: ComputedFromDateRatio,
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
ComputeIndexes,
|
||||
distribution::state::CohortState,
|
||||
indexes,
|
||||
internal::{ComputedFromHeightLast, CostBasisPercentiles},
|
||||
internal::{CostBasisPercentiles, PriceFromHeight},
|
||||
};
|
||||
|
||||
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: ComputedFromHeightLast<Dollars>,
|
||||
pub min: PriceFromHeight,
|
||||
|
||||
/// Maximum cost basis for any UTXO at this height
|
||||
pub max: ComputedFromHeightLast<Dollars>,
|
||||
pub max: PriceFromHeight,
|
||||
|
||||
/// Cost basis distribution percentiles (median, quartiles, etc.)
|
||||
pub percentiles: Option<CostBasisPercentiles>,
|
||||
@@ -32,13 +32,13 @@ impl CostBasisMetrics {
|
||||
let extended = cfg.extended();
|
||||
|
||||
Ok(Self {
|
||||
min: ComputedFromHeightLast::forced_import(
|
||||
min: PriceFromHeight::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("min_cost_basis"),
|
||||
cfg.version,
|
||||
cfg.indexes,
|
||||
)?,
|
||||
max: ComputedFromHeightLast::forced_import(
|
||||
max: PriceFromHeight::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("max_cost_basis"),
|
||||
cfg.version,
|
||||
|
||||
@@ -14,7 +14,8 @@ use crate::{
|
||||
internal::{
|
||||
ComputedFromHeightLast, ComputedFromHeightSum, ComputedFromHeightSumCum, ComputedFromDateLast,
|
||||
ComputedFromDateRatio, DollarsMinus, LazyBinaryFromHeightSum, LazyBinaryFromHeightSumCum,
|
||||
LazyFromHeightSum, LazyFromHeightSumCum, LazyFromDateLast, PercentageDollarsF32, StoredF32Identity,
|
||||
LazyFromHeightSum, LazyFromHeightSumCum, LazyFromDateLast, PercentageDollarsF32,
|
||||
PriceFromHeight, StoredF32Identity,
|
||||
},
|
||||
price,
|
||||
};
|
||||
@@ -26,7 +27,7 @@ use super::ImportConfig;
|
||||
pub struct RealizedMetrics {
|
||||
// === Realized Cap ===
|
||||
pub realized_cap: ComputedFromHeightLast<Dollars>,
|
||||
pub realized_price: ComputedFromHeightLast<Dollars>,
|
||||
pub realized_price: PriceFromHeight,
|
||||
pub realized_price_extra: ComputedFromDateRatio,
|
||||
pub realized_cap_rel_to_own_market_cap: Option<ComputedFromHeightLast<StoredF32>>,
|
||||
pub realized_cap_30d_delta: ComputedFromDateLast<Dollars>,
|
||||
@@ -169,7 +170,7 @@ impl RealizedMetrics {
|
||||
&realized_cap,
|
||||
);
|
||||
|
||||
let realized_price = ComputedFromHeightLast::forced_import(
|
||||
let realized_price = PriceFromHeight::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("realized_price"),
|
||||
cfg.version + v1,
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
//! Lazy binary price wrapper with both USD and sats representations.
|
||||
//!
|
||||
//! For binary operations (e.g., price × ratio) that produce price values.
|
||||
//! Both dollars and sats are computed lazily from the same sources.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, SatsFract, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{BinaryTransform, IterableCloneableVec, LazyVecFrom1};
|
||||
|
||||
use super::{ComputedFromDateLast, LazyBinaryFromDateLast};
|
||||
use crate::internal::{ComputedFromHeightLast, ComputedVecValue, DollarsToSatsFract, LazyTransformLast, NumericValue};
|
||||
|
||||
/// Lazy binary price with both USD and sats representations.
|
||||
///
|
||||
/// Wraps a binary operation that produces Dollars and lazily converts to sats.
|
||||
/// Derefs to the dollars metric.
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct LazyBinaryPrice<S1T, S2T>
|
||||
where
|
||||
S1T: ComputedVecValue,
|
||||
S2T: ComputedVecValue,
|
||||
{
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub dollars: LazyBinaryFromDateLast<Dollars, S1T, S2T>,
|
||||
pub sats: LazyUnaryFromBinaryLast<SatsFract, Dollars, S1T, S2T>,
|
||||
}
|
||||
|
||||
/// Lazy unary transform chain on a LazyBinaryFromDateLast output.
|
||||
#[derive(Clone, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct LazyUnaryFromBinaryLast<T, ST, S1T, S2T>
|
||||
where
|
||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||
ST: ComputedVecValue,
|
||||
S1T: ComputedVecValue,
|
||||
S2T: ComputedVecValue,
|
||||
{
|
||||
pub dateindex: LazyVecFrom1<brk_types::DateIndex, T, brk_types::DateIndex, ST>,
|
||||
pub weekindex: LazyTransformLast<brk_types::WeekIndex, T, ST>,
|
||||
pub monthindex: LazyTransformLast<brk_types::MonthIndex, T, ST>,
|
||||
pub quarterindex: LazyTransformLast<brk_types::QuarterIndex, T, ST>,
|
||||
pub semesterindex: LazyTransformLast<brk_types::SemesterIndex, T, ST>,
|
||||
pub yearindex: LazyTransformLast<brk_types::YearIndex, T, ST>,
|
||||
pub decadeindex: LazyTransformLast<brk_types::DecadeIndex, T, ST>,
|
||||
_phantom: std::marker::PhantomData<(S1T, S2T)>,
|
||||
}
|
||||
|
||||
impl<S1T, S2T> LazyBinaryPrice<S1T, S2T>
|
||||
where
|
||||
S1T: ComputedVecValue + JsonSchema + 'static,
|
||||
S2T: ComputedVecValue + JsonSchema + 'static,
|
||||
{
|
||||
/// Create from height-based price and dateindex-based ratio sources.
|
||||
pub fn from_height_and_dateindex_last<F: BinaryTransform<S1T, S2T, Dollars>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source1: &ComputedFromHeightLast<S1T>,
|
||||
source2: &ComputedFromDateLast<S2T>,
|
||||
) -> Self
|
||||
where
|
||||
S1T: NumericValue,
|
||||
{
|
||||
let dollars = LazyBinaryFromDateLast::from_height_and_dateindex_last::<F>(
|
||||
name, version, source1, source2,
|
||||
);
|
||||
Self::from_dollars(name, version, dollars)
|
||||
}
|
||||
|
||||
/// Create from two computed dateindex sources.
|
||||
pub fn from_computed_both_last<F: BinaryTransform<S1T, S2T, Dollars>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source1: &ComputedFromDateLast<S1T>,
|
||||
source2: &ComputedFromDateLast<S2T>,
|
||||
) -> Self {
|
||||
let dollars = LazyBinaryFromDateLast::from_computed_both_last::<F>(
|
||||
name, version, source1, source2,
|
||||
);
|
||||
Self::from_dollars(name, version, dollars)
|
||||
}
|
||||
|
||||
/// Create sats version from dollars.
|
||||
fn from_dollars(
|
||||
name: &str,
|
||||
version: Version,
|
||||
dollars: LazyBinaryFromDateLast<Dollars, S1T, S2T>,
|
||||
) -> Self {
|
||||
let sats_name = format!("{name}_sats");
|
||||
let sats = LazyUnaryFromBinaryLast {
|
||||
dateindex: LazyVecFrom1::transformed::<DollarsToSatsFract>(
|
||||
&sats_name,
|
||||
version,
|
||||
dollars.dateindex.boxed_clone(),
|
||||
),
|
||||
weekindex: LazyTransformLast::from_boxed::<DollarsToSatsFract>(
|
||||
&sats_name,
|
||||
version,
|
||||
dollars.weekindex.boxed_clone(),
|
||||
),
|
||||
monthindex: LazyTransformLast::from_boxed::<DollarsToSatsFract>(
|
||||
&sats_name,
|
||||
version,
|
||||
dollars.monthindex.boxed_clone(),
|
||||
),
|
||||
quarterindex: LazyTransformLast::from_boxed::<DollarsToSatsFract>(
|
||||
&sats_name,
|
||||
version,
|
||||
dollars.quarterindex.boxed_clone(),
|
||||
),
|
||||
semesterindex: LazyTransformLast::from_boxed::<DollarsToSatsFract>(
|
||||
&sats_name,
|
||||
version,
|
||||
dollars.semesterindex.boxed_clone(),
|
||||
),
|
||||
yearindex: LazyTransformLast::from_boxed::<DollarsToSatsFract>(
|
||||
&sats_name,
|
||||
version,
|
||||
dollars.yearindex.boxed_clone(),
|
||||
),
|
||||
decadeindex: LazyTransformLast::from_boxed::<DollarsToSatsFract>(
|
||||
&sats_name,
|
||||
version,
|
||||
dollars.decadeindex.boxed_clone(),
|
||||
),
|
||||
_phantom: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
Self { dollars, sats }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
//! Lazy price wrapper with both USD and sats representations.
|
||||
//!
|
||||
//! Both dollars and sats are computed from the same source.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, SatsFract, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::UnaryTransform;
|
||||
|
||||
use super::{ComputedFromDateLast, LazyFromDateLast};
|
||||
use crate::internal::{ComputedVecValue, DollarsToSatsFract};
|
||||
|
||||
/// Lazy price with both USD and sats representations.
|
||||
///
|
||||
/// Both are computed from the same source via separate transforms.
|
||||
/// Derefs to the dollars metric.
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct LazyPrice<ST>
|
||||
where
|
||||
ST: ComputedVecValue,
|
||||
{
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub dollars: LazyFromDateLast<Dollars, ST>,
|
||||
pub sats: LazyFromDateLast<SatsFract, ST>,
|
||||
}
|
||||
|
||||
/// Composed transform: ST -> Dollars -> SatsFract
|
||||
pub struct ComposedDollarsToSatsFract<F>(std::marker::PhantomData<F>);
|
||||
|
||||
impl<F, ST> UnaryTransform<ST, SatsFract> for ComposedDollarsToSatsFract<F>
|
||||
where
|
||||
F: UnaryTransform<ST, Dollars>,
|
||||
{
|
||||
#[inline(always)]
|
||||
fn apply(source: ST) -> SatsFract {
|
||||
DollarsToSatsFract::apply(F::apply(source))
|
||||
}
|
||||
}
|
||||
|
||||
impl<ST> LazyPrice<ST>
|
||||
where
|
||||
ST: ComputedVecValue + schemars::JsonSchema + 'static,
|
||||
{
|
||||
pub fn from_source<F: UnaryTransform<ST, Dollars>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &ComputedFromDateLast<ST>,
|
||||
) -> Self {
|
||||
let dollars = LazyFromDateLast::from_source::<F>(name, version, source);
|
||||
let sats = LazyFromDateLast::from_source::<ComposedDollarsToSatsFract<F>>(
|
||||
&format!("{name}_sats"),
|
||||
version,
|
||||
source,
|
||||
);
|
||||
Self { dollars, sats }
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,20 @@ mod binary_sum_cum;
|
||||
mod first;
|
||||
mod last;
|
||||
mod lazy;
|
||||
mod lazy_binary_price;
|
||||
mod lazy_distribution;
|
||||
mod lazy_full;
|
||||
mod lazy_last;
|
||||
mod lazy_price;
|
||||
mod lazy_sum;
|
||||
mod lazy_sum_cum;
|
||||
mod max;
|
||||
mod min;
|
||||
mod percentiles;
|
||||
mod price;
|
||||
mod ratio;
|
||||
mod stddev;
|
||||
mod unary_last;
|
||||
mod value_derived_last;
|
||||
mod value_last;
|
||||
mod value_lazy_last;
|
||||
@@ -26,16 +30,20 @@ pub use binary_sum_cum::*;
|
||||
pub use first::*;
|
||||
pub use last::*;
|
||||
pub use lazy::*;
|
||||
pub use lazy_binary_price::*;
|
||||
pub use lazy_distribution::*;
|
||||
pub use lazy_full::*;
|
||||
pub use lazy_last::*;
|
||||
pub use lazy_price::*;
|
||||
pub use lazy_sum::*;
|
||||
pub use lazy_sum_cum::*;
|
||||
pub use max::*;
|
||||
pub use min::*;
|
||||
pub use percentiles::*;
|
||||
pub use price::*;
|
||||
pub use ratio::*;
|
||||
pub use stddev::*;
|
||||
pub use unary_last::*;
|
||||
pub use value_derived_last::*;
|
||||
pub use value_last::*;
|
||||
pub use value_lazy_last::*;
|
||||
|
||||
@@ -8,7 +8,7 @@ use vecdb::{
|
||||
|
||||
use crate::{ComputeIndexes, indexes};
|
||||
|
||||
use super::ComputedFromDateLast;
|
||||
use super::Price;
|
||||
|
||||
pub const PERCENTILES: [u8; 19] = [
|
||||
5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95,
|
||||
@@ -17,7 +17,7 @@ pub const PERCENTILES_LEN: usize = PERCENTILES.len();
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CostBasisPercentiles {
|
||||
pub vecs: [Option<ComputedFromDateLast<Dollars>>; PERCENTILES_LEN],
|
||||
pub vecs: [Option<Price>; PERCENTILES_LEN],
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
@@ -37,8 +37,7 @@ impl CostBasisPercentiles {
|
||||
} else {
|
||||
format!("{name}_cost_basis_pct{p:02}")
|
||||
};
|
||||
ComputedFromDateLast::forced_import(db, &metric_name, version + VERSION, indexes)
|
||||
.unwrap()
|
||||
Price::forced_import(db, &metric_name, version + VERSION, indexes).unwrap()
|
||||
})
|
||||
});
|
||||
|
||||
@@ -81,7 +80,7 @@ impl CostBasisPercentiles {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get(&self, percentile: u8) -> Option<&ComputedFromDateLast<Dollars>> {
|
||||
pub fn get(&self, percentile: u8) -> Option<&Price> {
|
||||
PERCENTILES
|
||||
.iter()
|
||||
.position(|&p| p == percentile)
|
||||
|
||||
48
crates/brk_computer/src/internal/multi/from_date/price.rs
Normal file
48
crates/brk_computer/src/internal/multi/from_date/price.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
//! Price wrapper that provides both USD and sats representations.
|
||||
//!
|
||||
//! The struct derefs to dollars, making it transparent for existing code.
|
||||
//! Access `.sats` for the sats representation.
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, SatsFract, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::Database;
|
||||
|
||||
use super::{ComputedFromDateLast, LazyUnaryFromDateLast};
|
||||
use crate::{indexes, internal::DollarsToSatsFract};
|
||||
|
||||
/// Price metric with both USD and sats representations.
|
||||
///
|
||||
/// Derefs to the dollars metric, so existing code works unchanged.
|
||||
/// Access `.sats` for the sats exchange rate version.
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct Price {
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub dollars: ComputedFromDateLast<Dollars>,
|
||||
pub sats: LazyUnaryFromDateLast<SatsFract, Dollars>,
|
||||
}
|
||||
|
||||
impl Price {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let dollars = ComputedFromDateLast::forced_import(db, name, version, indexes)?;
|
||||
Ok(Self::from_computed(name, version, dollars))
|
||||
}
|
||||
|
||||
pub fn from_computed(name: &str, version: Version, dollars: ComputedFromDateLast<Dollars>) -> Self {
|
||||
let sats = LazyUnaryFromDateLast::from_computed_last::<DollarsToSatsFract>(
|
||||
&format!("{name}_sats"),
|
||||
version,
|
||||
&dollars,
|
||||
);
|
||||
Self { dollars, sats }
|
||||
}
|
||||
}
|
||||
@@ -9,19 +9,19 @@ use vecdb::{
|
||||
use crate::{
|
||||
ComputeIndexes, indexes,
|
||||
internal::{
|
||||
ComputedFromDateStdDev, LazyBinaryFromDateLast, PriceTimesRatio,
|
||||
ComputedFromDateStdDev, LazyBinaryPrice, PriceTimesRatio,
|
||||
StandardDeviationVecsOptions,
|
||||
},
|
||||
price,
|
||||
utils::get_percentile,
|
||||
};
|
||||
|
||||
use super::ComputedFromDateLast;
|
||||
use super::{ComputedFromDateLast, Price};
|
||||
use crate::internal::ComputedFromHeightLast;
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct ComputedFromDateRatio {
|
||||
pub price: Option<ComputedFromDateLast<Dollars>>,
|
||||
pub price: Option<Price>,
|
||||
|
||||
pub ratio: ComputedFromDateLast<StoredF32>,
|
||||
pub ratio_1w_sma: Option<ComputedFromDateLast<StoredF32>>,
|
||||
@@ -32,12 +32,12 @@ pub struct ComputedFromDateRatio {
|
||||
pub ratio_pct5: Option<ComputedFromDateLast<StoredF32>>,
|
||||
pub ratio_pct2: Option<ComputedFromDateLast<StoredF32>>,
|
||||
pub ratio_pct1: Option<ComputedFromDateLast<StoredF32>>,
|
||||
pub ratio_pct99_usd: Option<LazyBinaryFromDateLast<Dollars, Dollars, StoredF32>>,
|
||||
pub ratio_pct98_usd: Option<LazyBinaryFromDateLast<Dollars, Dollars, StoredF32>>,
|
||||
pub ratio_pct95_usd: Option<LazyBinaryFromDateLast<Dollars, Dollars, StoredF32>>,
|
||||
pub ratio_pct5_usd: Option<LazyBinaryFromDateLast<Dollars, Dollars, StoredF32>>,
|
||||
pub ratio_pct2_usd: Option<LazyBinaryFromDateLast<Dollars, Dollars, StoredF32>>,
|
||||
pub ratio_pct1_usd: Option<LazyBinaryFromDateLast<Dollars, Dollars, StoredF32>>,
|
||||
pub ratio_pct99_usd: Option<LazyBinaryPrice<Dollars, StoredF32>>,
|
||||
pub ratio_pct98_usd: Option<LazyBinaryPrice<Dollars, StoredF32>>,
|
||||
pub ratio_pct95_usd: Option<LazyBinaryPrice<Dollars, StoredF32>>,
|
||||
pub ratio_pct5_usd: Option<LazyBinaryPrice<Dollars, StoredF32>>,
|
||||
pub ratio_pct2_usd: Option<LazyBinaryPrice<Dollars, StoredF32>>,
|
||||
pub ratio_pct1_usd: Option<LazyBinaryPrice<Dollars, StoredF32>>,
|
||||
|
||||
pub ratio_sd: Option<ComputedFromDateStdDev>,
|
||||
pub ratio_4y_sd: Option<ComputedFromDateStdDev>,
|
||||
@@ -70,7 +70,7 @@ impl ComputedFromDateRatio {
|
||||
// Only compute internally when metric_price is None
|
||||
let price = metric_price
|
||||
.is_none()
|
||||
.then(|| ComputedFromDateLast::forced_import(db, name, v, indexes).unwrap());
|
||||
.then(|| Price::forced_import(db, name, v, indexes).unwrap());
|
||||
|
||||
macro_rules! import_sd {
|
||||
($suffix:expr, $days:expr) => {
|
||||
@@ -98,7 +98,7 @@ impl ComputedFromDateRatio {
|
||||
($ratio:expr, $suffix:expr) => {
|
||||
if let Some(mp) = metric_price {
|
||||
$ratio.as_ref().map(|r| {
|
||||
LazyBinaryFromDateLast::from_height_and_dateindex_last::<PriceTimesRatio>(
|
||||
LazyBinaryPrice::from_height_and_dateindex_last::<PriceTimesRatio>(
|
||||
&format!("{name}_{}", $suffix),
|
||||
v,
|
||||
mp,
|
||||
@@ -107,7 +107,7 @@ impl ComputedFromDateRatio {
|
||||
})
|
||||
} else {
|
||||
price.as_ref().zip($ratio.as_ref()).map(|(p, r)| {
|
||||
LazyBinaryFromDateLast::from_computed_both_last::<PriceTimesRatio>(
|
||||
LazyBinaryPrice::from_computed_both_last::<PriceTimesRatio>(
|
||||
&format!("{name}_{}", $suffix),
|
||||
v,
|
||||
p,
|
||||
|
||||
@@ -10,7 +10,7 @@ use vecdb::{
|
||||
|
||||
use crate::{ComputeIndexes, indexes, price};
|
||||
|
||||
use crate::internal::{ClosePriceTimesRatio, ComputedFromDateLast, LazyBinaryFromDateLast};
|
||||
use crate::internal::{ClosePriceTimesRatio, ComputedFromDateLast, LazyBinaryPrice};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct ComputedFromDateStdDev {
|
||||
@@ -35,19 +35,19 @@ pub struct ComputedFromDateStdDev {
|
||||
pub m2_5sd: Option<ComputedFromDateLast<StoredF32>>,
|
||||
pub m3sd: Option<ComputedFromDateLast<StoredF32>>,
|
||||
|
||||
pub _0sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub p0_5sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub p1sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub p1_5sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub p2sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub p2_5sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub p3sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub m0_5sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub m1sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub m1_5sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub m2sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub m2_5sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub m3sd_usd: Option<LazyBinaryFromDateLast<Dollars, Close<Dollars>, StoredF32>>,
|
||||
pub _0sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub p0_5sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub p1sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub p1_5sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub p2sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub p2_5sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub p3sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub m0_5sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub m1sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub m1_5sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub m2sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub m2_5sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
pub m3sd_usd: Option<LazyBinaryPrice<Close<Dollars>, StoredF32>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@@ -140,7 +140,7 @@ impl ComputedFromDateStdDev {
|
||||
.zip($band.as_ref())
|
||||
.filter(|_| options.price_bands())
|
||||
.map(|(p, b)| {
|
||||
LazyBinaryFromDateLast::from_computed_both_last::<ClosePriceTimesRatio>(
|
||||
LazyBinaryPrice::from_computed_both_last::<ClosePriceTimesRatio>(
|
||||
&format!("{name}_{}", $suffix),
|
||||
version,
|
||||
p,
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//! Unary transform composite from DateIndex - Last aggregation only.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
DateIndex, DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, Version, WeekIndex, YearIndex,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{IterableCloneableVec, LazyVecFrom1, UnaryTransform};
|
||||
|
||||
use crate::internal::{ComputedFromDateLast, ComputedVecValue, LazyTransformLast};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct LazyUnaryFromDateLast<T, ST>
|
||||
where
|
||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||
ST: ComputedVecValue,
|
||||
{
|
||||
pub dateindex: LazyVecFrom1<DateIndex, T, DateIndex, ST>,
|
||||
pub weekindex: LazyTransformLast<WeekIndex, T, ST>,
|
||||
pub monthindex: LazyTransformLast<MonthIndex, T, ST>,
|
||||
pub quarterindex: LazyTransformLast<QuarterIndex, T, ST>,
|
||||
pub semesterindex: LazyTransformLast<SemesterIndex, T, ST>,
|
||||
pub yearindex: LazyTransformLast<YearIndex, T, ST>,
|
||||
pub decadeindex: LazyTransformLast<DecadeIndex, T, ST>,
|
||||
}
|
||||
|
||||
impl<T, ST> LazyUnaryFromDateLast<T, ST>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema + 'static,
|
||||
ST: ComputedVecValue + JsonSchema,
|
||||
{
|
||||
pub fn from_computed_last<F: UnaryTransform<ST, T>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &ComputedFromDateLast<ST>,
|
||||
) -> Self {
|
||||
let v = version + VERSION;
|
||||
|
||||
macro_rules! period {
|
||||
($p:ident) => {
|
||||
LazyTransformLast::from_lazy_last::<F, _, _>(name, v, &source.$p)
|
||||
};
|
||||
}
|
||||
|
||||
Self {
|
||||
dateindex: LazyVecFrom1::transformed::<F>(name, v, source.dateindex.boxed_clone()),
|
||||
weekindex: period!(weekindex),
|
||||
monthindex: period!(monthindex),
|
||||
quarterindex: period!(quarterindex),
|
||||
semesterindex: period!(semesterindex),
|
||||
yearindex: period!(yearindex),
|
||||
decadeindex: period!(decadeindex),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ mod lazy_computed_full;
|
||||
mod lazy_computed_sum_cum;
|
||||
mod lazy_last;
|
||||
mod lazy_sum;
|
||||
mod price;
|
||||
mod unary_last;
|
||||
mod lazy_sum_cum;
|
||||
mod sum;
|
||||
mod sum_cum;
|
||||
@@ -46,6 +48,8 @@ pub use lazy_computed_full::*;
|
||||
pub use lazy_computed_sum_cum::*;
|
||||
pub use lazy_last::*;
|
||||
pub use lazy_sum::*;
|
||||
pub use price::*;
|
||||
pub use unary_last::*;
|
||||
pub use lazy_sum_cum::*;
|
||||
pub use sum::*;
|
||||
pub use sum_cum::*;
|
||||
|
||||
49
crates/brk_computer/src/internal/multi/from_height/price.rs
Normal file
49
crates/brk_computer/src/internal/multi/from_height/price.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
//! Price wrapper for height-based metrics with both USD and sats representations.
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, SatsFract, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::Database;
|
||||
|
||||
use super::{ComputedFromHeightLast, LazyUnaryFromHeightLast};
|
||||
use crate::{indexes, internal::DollarsToSatsFract};
|
||||
|
||||
/// Price metric (height-based) with both USD and sats representations.
|
||||
///
|
||||
/// Derefs to the dollars metric, so existing code works unchanged.
|
||||
/// Access `.sats` for the sats exchange rate version.
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct PriceFromHeight {
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub dollars: ComputedFromHeightLast<Dollars>,
|
||||
pub sats: LazyUnaryFromHeightLast<SatsFract, Dollars>,
|
||||
}
|
||||
|
||||
impl PriceFromHeight {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let dollars = ComputedFromHeightLast::forced_import(db, name, version, indexes)?;
|
||||
Ok(Self::from_computed(name, version, dollars))
|
||||
}
|
||||
|
||||
pub fn from_computed(
|
||||
name: &str,
|
||||
version: Version,
|
||||
dollars: ComputedFromHeightLast<Dollars>,
|
||||
) -> Self {
|
||||
let sats = LazyUnaryFromHeightLast::from_computed_last::<DollarsToSatsFract>(
|
||||
&format!("{name}_sats"),
|
||||
version,
|
||||
&dollars,
|
||||
);
|
||||
Self { dollars, sats }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//! Unary transform composite from Height - Last aggregation only.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, SemesterIndex,
|
||||
Version, WeekIndex, YearIndex,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{IterableCloneableVec, LazyVecFrom1, UnaryTransform};
|
||||
|
||||
use crate::internal::{
|
||||
ComputedFromHeightLast, ComputedVecValue, LazyTransformLast, NumericValue,
|
||||
};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct LazyUnaryFromHeightLast<T, ST>
|
||||
where
|
||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||
ST: ComputedVecValue,
|
||||
{
|
||||
pub height: LazyVecFrom1<Height, T, Height, ST>,
|
||||
pub dateindex: LazyTransformLast<DateIndex, T, ST>,
|
||||
pub weekindex: LazyTransformLast<WeekIndex, T, ST>,
|
||||
pub monthindex: LazyTransformLast<MonthIndex, T, ST>,
|
||||
pub quarterindex: LazyTransformLast<QuarterIndex, T, ST>,
|
||||
pub semesterindex: LazyTransformLast<SemesterIndex, T, ST>,
|
||||
pub yearindex: LazyTransformLast<YearIndex, T, ST>,
|
||||
pub decadeindex: LazyTransformLast<DecadeIndex, T, ST>,
|
||||
pub difficultyepoch: LazyTransformLast<DifficultyEpoch, T, ST>,
|
||||
}
|
||||
|
||||
impl<T, ST> LazyUnaryFromHeightLast<T, ST>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema + 'static,
|
||||
ST: NumericValue + JsonSchema,
|
||||
{
|
||||
pub fn from_computed_last<F: UnaryTransform<ST, T>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &ComputedFromHeightLast<ST>,
|
||||
) -> Self {
|
||||
let v = version + VERSION;
|
||||
|
||||
macro_rules! period {
|
||||
($p:ident) => {
|
||||
LazyTransformLast::from_lazy_last::<F, _, _>(name, v, &source.$p)
|
||||
};
|
||||
}
|
||||
|
||||
Self {
|
||||
height: LazyVecFrom1::transformed::<F>(name, v, source.height.boxed_clone()),
|
||||
dateindex: LazyTransformLast::from_last_vec::<F>(name, v, &source.rest.dateindex),
|
||||
weekindex: period!(weekindex),
|
||||
monthindex: period!(monthindex),
|
||||
quarterindex: period!(quarterindex),
|
||||
semesterindex: period!(semesterindex),
|
||||
yearindex: period!(yearindex),
|
||||
decadeindex: period!(decadeindex),
|
||||
difficultyepoch: period!(difficultyepoch),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ mod last;
|
||||
mod lazy_ohlc;
|
||||
mod max;
|
||||
mod min;
|
||||
mod price;
|
||||
mod unary_last;
|
||||
mod value_last;
|
||||
|
||||
pub use binary_last::*;
|
||||
@@ -16,4 +18,6 @@ pub use last::*;
|
||||
pub use lazy_ohlc::*;
|
||||
pub use max::*;
|
||||
pub use min::*;
|
||||
pub use price::*;
|
||||
pub use unary_last::*;
|
||||
pub use value_last::*;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
//! Price wrapper for height+date-based metrics with both USD and sats representations.
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, SatsFract, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::Database;
|
||||
|
||||
use super::{ComputedFromHeightAndDateLast, LazyUnaryFromHeightAndDateLast};
|
||||
use crate::{indexes, internal::DollarsToSatsFract};
|
||||
|
||||
/// Price metric (height+date-based) with both USD and sats representations.
|
||||
///
|
||||
/// Derefs to the dollars metric, so existing code works unchanged.
|
||||
/// Access `.sats` for the sats exchange rate version.
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct PriceFromHeightAndDate {
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub dollars: ComputedFromHeightAndDateLast<Dollars>,
|
||||
pub sats: LazyUnaryFromHeightAndDateLast<SatsFract, Dollars>,
|
||||
}
|
||||
|
||||
impl PriceFromHeightAndDate {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let dollars = ComputedFromHeightAndDateLast::forced_import(db, name, version, indexes)?;
|
||||
Ok(Self::from_computed(name, version, dollars))
|
||||
}
|
||||
|
||||
pub fn from_computed(
|
||||
name: &str,
|
||||
version: Version,
|
||||
dollars: ComputedFromHeightAndDateLast<Dollars>,
|
||||
) -> Self {
|
||||
let sats = LazyUnaryFromHeightAndDateLast::from_computed_last::<DollarsToSatsFract>(
|
||||
&format!("{name}_sats"),
|
||||
version,
|
||||
&dollars,
|
||||
);
|
||||
Self { dollars, sats }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//! Unary transform composite from Height+Date - Last aggregation only.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, SemesterIndex,
|
||||
Version, WeekIndex, YearIndex,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{IterableCloneableVec, LazyVecFrom1, UnaryTransform};
|
||||
|
||||
use crate::internal::{ComputedFromHeightAndDateLast, ComputedVecValue, LazyTransformLast};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct LazyUnaryFromHeightAndDateLast<T, ST>
|
||||
where
|
||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||
ST: ComputedVecValue,
|
||||
{
|
||||
pub height: LazyVecFrom1<Height, T, Height, ST>,
|
||||
pub dateindex: LazyTransformLast<DateIndex, T, ST>,
|
||||
pub weekindex: LazyTransformLast<WeekIndex, T, ST>,
|
||||
pub monthindex: LazyTransformLast<MonthIndex, T, ST>,
|
||||
pub quarterindex: LazyTransformLast<QuarterIndex, T, ST>,
|
||||
pub semesterindex: LazyTransformLast<SemesterIndex, T, ST>,
|
||||
pub yearindex: LazyTransformLast<YearIndex, T, ST>,
|
||||
pub decadeindex: LazyTransformLast<DecadeIndex, T, ST>,
|
||||
pub difficultyepoch: LazyTransformLast<DifficultyEpoch, T, ST>,
|
||||
}
|
||||
|
||||
impl<T, ST> LazyUnaryFromHeightAndDateLast<T, ST>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema + 'static,
|
||||
ST: ComputedVecValue + JsonSchema,
|
||||
{
|
||||
pub fn from_computed_last<F: UnaryTransform<ST, T>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &ComputedFromHeightAndDateLast<ST>,
|
||||
) -> Self {
|
||||
let v = version + VERSION;
|
||||
|
||||
macro_rules! period {
|
||||
($p:ident) => {
|
||||
LazyTransformLast::from_lazy_last::<F, _, _>(name, v, &source.rest.$p)
|
||||
};
|
||||
}
|
||||
|
||||
Self {
|
||||
height: LazyVecFrom1::transformed::<F>(name, v, source.height.boxed_clone()),
|
||||
dateindex: LazyTransformLast(LazyVecFrom1::transformed::<F>(
|
||||
name,
|
||||
v,
|
||||
source.rest.dateindex.boxed_clone(),
|
||||
)),
|
||||
weekindex: period!(weekindex),
|
||||
monthindex: period!(monthindex),
|
||||
quarterindex: period!(quarterindex),
|
||||
semesterindex: period!(semesterindex),
|
||||
yearindex: period!(yearindex),
|
||||
decadeindex: period!(decadeindex),
|
||||
difficultyepoch: LazyTransformLast::from_lazy_last::<F, _, _>(
|
||||
name,
|
||||
v,
|
||||
&source.difficultyepoch,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
use brk_types::{Close, Dollars, SatsFract};
|
||||
use brk_types::{Dollars, SatsFract};
|
||||
use vecdb::UnaryTransform;
|
||||
|
||||
/// Dollars -> SatsFract (exchange rate: sats per dollar at this price level)
|
||||
@@ -8,21 +8,6 @@ pub struct DollarsToSatsFract;
|
||||
impl UnaryTransform<Dollars, SatsFract> for DollarsToSatsFract {
|
||||
#[inline(always)]
|
||||
fn apply(usd: Dollars) -> SatsFract {
|
||||
let usd_f64 = f64::from(usd);
|
||||
if usd_f64 == 0.0 {
|
||||
SatsFract::NAN
|
||||
} else {
|
||||
SatsFract::from(SatsFract::SATS_PER_BTC / usd_f64)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Close<Dollars> -> SatsFract
|
||||
pub struct CloseDollarsToSatsFract;
|
||||
|
||||
impl UnaryTransform<Close<Dollars>, SatsFract> for CloseDollarsToSatsFract {
|
||||
#[inline(always)]
|
||||
fn apply(usd: Close<Dollars>) -> SatsFract {
|
||||
DollarsToSatsFract::apply(*usd)
|
||||
SatsFract::ONE_BTC / usd
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ mod close_price_times_sats;
|
||||
mod difference_f32;
|
||||
mod dollar_halve;
|
||||
mod dollar_identity;
|
||||
mod dollars_to_sats_fract;
|
||||
mod dollar_minus;
|
||||
mod dollar_plus;
|
||||
mod dollar_times_tenths;
|
||||
@@ -44,6 +45,7 @@ pub use close_price_times_sats::*;
|
||||
pub use difference_f32::*;
|
||||
pub use dollar_halve::*;
|
||||
pub use dollar_identity::*;
|
||||
pub use dollars_to_sats_fract::*;
|
||||
pub use dollar_minus::*;
|
||||
pub use dollar_plus::*;
|
||||
pub use dollar_times_tenths::*;
|
||||
|
||||
@@ -6,8 +6,8 @@ use super::Vecs;
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
ComputedFromDateLast, ComputedFromHeightAndDateLast, LazyBinaryFromHeightAndDateLast, LazyFromDateLast,
|
||||
PercentageDiffCloseDollars, StoredU16ToYears,
|
||||
ComputedFromDateLast, LazyBinaryFromHeightAndDateLast, LazyFromDateLast,
|
||||
PercentageDiffCloseDollars, PriceFromHeightAndDate, StoredU16ToYears,
|
||||
},
|
||||
price,
|
||||
};
|
||||
@@ -19,7 +19,7 @@ impl Vecs {
|
||||
indexes: &indexes::Vecs,
|
||||
price: &price::Vecs,
|
||||
) -> Result<Self> {
|
||||
let price_ath = ComputedFromHeightAndDateLast::forced_import(db, "price_ath", version, indexes)?;
|
||||
let price_ath = PriceFromHeightAndDate::forced_import(db, "price_ath", version, indexes)?;
|
||||
|
||||
let max_days_between_price_aths =
|
||||
ComputedFromDateLast::forced_import(db, "max_days_between_price_aths", version, indexes)?;
|
||||
|
||||
@@ -2,13 +2,13 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{Close, Dollars, StoredF32, StoredU16};
|
||||
|
||||
use crate::internal::{
|
||||
ComputedFromDateLast, ComputedFromHeightAndDateLast, LazyBinaryFromHeightAndDateLast, LazyFromDateLast,
|
||||
ComputedFromDateLast, LazyBinaryFromHeightAndDateLast, LazyFromDateLast, PriceFromHeightAndDate,
|
||||
};
|
||||
|
||||
/// All-time high related metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub price_ath: ComputedFromHeightAndDateLast<Dollars>,
|
||||
pub price_ath: PriceFromHeightAndDate,
|
||||
pub price_drawdown: LazyBinaryFromHeightAndDateLast<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub days_since_price_ath: ComputedFromDateLast<StoredU16>,
|
||||
pub years_since_price_ath: LazyFromDateLast<StoredF32, StoredU16>,
|
||||
|
||||
@@ -6,7 +6,7 @@ use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod, DCA_CLASS_NAMES, DCA_PERIOD_NAME
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
ComputedFromDateLast, LazyBinaryFromDateLast, PercentageDiffCloseDollars,
|
||||
ComputedFromDateLast, LazyBinaryFromDateLast, PercentageDiffCloseDollars, Price,
|
||||
ValueFromDateLast,
|
||||
},
|
||||
market::lookback,
|
||||
@@ -28,12 +28,7 @@ impl Vecs {
|
||||
|
||||
// DCA by period - average price
|
||||
let period_average_price = ByDcaPeriod::try_new(|name, _days| {
|
||||
ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
&format!("{name}_dca_average_price"),
|
||||
version,
|
||||
indexes,
|
||||
)
|
||||
Price::forced_import(db, &format!("{name}_dca_average_price"), version, indexes)
|
||||
})?;
|
||||
|
||||
let period_returns =
|
||||
@@ -160,7 +155,7 @@ impl Vecs {
|
||||
|
||||
// DCA by year class - average price
|
||||
let class_average_price = ByDcaClass::try_new(|name, _year, _dateindex| {
|
||||
ComputedFromDateLast::forced_import(db, &format!("{name}_average_price"), version, indexes)
|
||||
Price::forced_import(db, &format!("{name}_average_price"), version, indexes)
|
||||
})?;
|
||||
|
||||
let class_returns =
|
||||
|
||||
@@ -2,14 +2,14 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{Close, Dollars, StoredF32, StoredU32};
|
||||
|
||||
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod};
|
||||
use crate::internal::{ComputedFromDateLast, LazyBinaryFromDateLast, ValueFromDateLast};
|
||||
use crate::internal::{ComputedFromDateLast, LazyBinaryFromDateLast, Price, ValueFromDateLast};
|
||||
|
||||
/// Dollar-cost averaging metrics by time period and year class
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
// DCA by period - KISS types
|
||||
pub period_stack: ByDcaPeriod<ValueFromDateLast>,
|
||||
pub period_average_price: ByDcaPeriod<ComputedFromDateLast<Dollars>>,
|
||||
pub period_average_price: ByDcaPeriod<Price>,
|
||||
pub period_returns: ByDcaPeriod<LazyBinaryFromDateLast<StoredF32, Close<Dollars>, Dollars>>,
|
||||
pub period_cagr: ByDcaCagr<ComputedFromDateLast<StoredF32>>,
|
||||
|
||||
@@ -31,7 +31,7 @@ pub struct Vecs {
|
||||
|
||||
// DCA by year class - KISS types
|
||||
pub class_stack: ByDcaClass<ValueFromDateLast>,
|
||||
pub class_average_price: ByDcaClass<ComputedFromDateLast<Dollars>>,
|
||||
pub class_average_price: ByDcaClass<Price>,
|
||||
pub class_returns: ByDcaClass<LazyBinaryFromDateLast<StoredF32, Close<Dollars>, Dollars>>,
|
||||
|
||||
// DCA by year class - profitability
|
||||
|
||||
@@ -3,12 +3,12 @@ use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::{ByLookbackPeriod, Vecs};
|
||||
use crate::{indexes, internal::ComputedFromDateLast};
|
||||
use crate::{indexes, internal::Price};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(db: &Database, version: Version, indexes: &indexes::Vecs) -> Result<Self> {
|
||||
let price_ago = ByLookbackPeriod::try_new(|name, _days| {
|
||||
ComputedFromDateLast::forced_import(db, &format!("price_{name}_ago"), version, indexes)
|
||||
Price::forced_import(db, &format!("price_{name}_ago"), version, indexes)
|
||||
})?;
|
||||
|
||||
Ok(Self { price_ago })
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Dollars;
|
||||
|
||||
use super::ByLookbackPeriod;
|
||||
use crate::internal::ComputedFromDateLast;
|
||||
use crate::internal::Price;
|
||||
|
||||
/// Price lookback metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
#[traversable(flatten)]
|
||||
pub price_ago: ByLookbackPeriod<ComputedFromDateLast<Dollars>>,
|
||||
pub price_ago: ByLookbackPeriod<Price>,
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use vecdb::Database;
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{ComputedFromDateRatio, DollarsTimesTenths, LazyFromDateLast},
|
||||
internal::{ComputedFromDateRatio, DollarsTimesTenths, LazyPrice},
|
||||
price,
|
||||
};
|
||||
|
||||
@@ -307,19 +307,19 @@ impl Vecs {
|
||||
)?;
|
||||
|
||||
let price_200d_sma_source = price_200d_sma.price.as_ref().unwrap();
|
||||
let price_200d_sma_x2_4 = LazyFromDateLast::from_source::<DollarsTimesTenths<24>>(
|
||||
let price_200d_sma_x2_4 = LazyPrice::from_source::<DollarsTimesTenths<24>>(
|
||||
"price_200d_sma_x2_4",
|
||||
version,
|
||||
price_200d_sma_source,
|
||||
);
|
||||
let price_200d_sma_x0_8 = LazyFromDateLast::from_source::<DollarsTimesTenths<8>>(
|
||||
let price_200d_sma_x0_8 = LazyPrice::from_source::<DollarsTimesTenths<8>>(
|
||||
"price_200d_sma_x0_8",
|
||||
version,
|
||||
price_200d_sma_source,
|
||||
);
|
||||
|
||||
let price_350d_sma_source = price_350d_sma.price.as_ref().unwrap();
|
||||
let price_350d_sma_x2 = LazyFromDateLast::from_source::<DollarsTimesTenths<20>>(
|
||||
let price_350d_sma_x2 = LazyPrice::from_source::<DollarsTimesTenths<20>>(
|
||||
"price_350d_sma_x2",
|
||||
version,
|
||||
price_350d_sma_source,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Dollars;
|
||||
|
||||
use crate::internal::{ComputedFromDateRatio, LazyFromDateLast};
|
||||
use crate::internal::{ComputedFromDateRatio, LazyPrice};
|
||||
|
||||
/// Simple and exponential moving average metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
@@ -40,7 +40,7 @@ pub struct Vecs {
|
||||
pub price_200w_ema: ComputedFromDateRatio,
|
||||
pub price_4y_ema: ComputedFromDateRatio,
|
||||
|
||||
pub price_200d_sma_x2_4: LazyFromDateLast<Dollars>,
|
||||
pub price_200d_sma_x0_8: LazyFromDateLast<Dollars>,
|
||||
pub price_350d_sma_x2: LazyFromDateLast<Dollars>,
|
||||
pub price_200d_sma_x2_4: LazyPrice<Dollars>,
|
||||
pub price_200d_sma_x0_8: LazyPrice<Dollars>,
|
||||
pub price_350d_sma_x2: LazyPrice<Dollars>,
|
||||
}
|
||||
|
||||
@@ -3,67 +3,23 @@ use brk_types::Version;
|
||||
use vecdb::{Database, EagerVec, ImportableVec};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{indexes, internal::ComputedFromDateLast};
|
||||
use crate::{indexes, internal::{ComputedFromDateLast, Price}};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(db: &Database, version: Version, indexes: &indexes::Vecs) -> Result<Self> {
|
||||
let v1 = Version::ONE;
|
||||
|
||||
Ok(Self {
|
||||
price_1w_min: ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
"price_1w_min",
|
||||
version + v1,
|
||||
indexes,
|
||||
)?,
|
||||
price_1w_max: ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
"price_1w_max",
|
||||
version + v1,
|
||||
indexes,
|
||||
)?,
|
||||
price_2w_min: ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
"price_2w_min",
|
||||
version + v1,
|
||||
indexes,
|
||||
)?,
|
||||
price_2w_max: ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
"price_2w_max",
|
||||
version + v1,
|
||||
indexes,
|
||||
)?,
|
||||
price_1m_min: ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
"price_1m_min",
|
||||
version + v1,
|
||||
indexes,
|
||||
)?,
|
||||
price_1m_max: ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
"price_1m_max",
|
||||
version + v1,
|
||||
indexes,
|
||||
)?,
|
||||
price_1y_min: ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
"price_1y_min",
|
||||
version + v1,
|
||||
indexes,
|
||||
)?,
|
||||
price_1y_max: ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
"price_1y_max",
|
||||
version + v1,
|
||||
indexes,
|
||||
)?,
|
||||
price_1w_min: Price::forced_import(db, "price_1w_min", version + v1, indexes)?,
|
||||
price_1w_max: Price::forced_import(db, "price_1w_max", version + v1, indexes)?,
|
||||
price_2w_min: Price::forced_import(db, "price_2w_min", version + v1, indexes)?,
|
||||
price_2w_max: Price::forced_import(db, "price_2w_max", version + v1, indexes)?,
|
||||
price_1m_min: Price::forced_import(db, "price_1m_min", version + v1, indexes)?,
|
||||
price_1m_max: Price::forced_import(db, "price_1m_max", version + v1, indexes)?,
|
||||
price_1y_min: Price::forced_import(db, "price_1y_min", version + v1, indexes)?,
|
||||
price_1y_max: Price::forced_import(db, "price_1y_max", version + v1, indexes)?,
|
||||
price_true_range: EagerVec::forced_import(db, "price_true_range", version)?,
|
||||
price_true_range_2w_sum: EagerVec::forced_import(
|
||||
db,
|
||||
"price_true_range_2w_sum",
|
||||
version,
|
||||
)?,
|
||||
price_true_range_2w_sum: EagerVec::forced_import(db, "price_true_range_2w_sum", version)?,
|
||||
price_2w_choppiness_index: ComputedFromDateLast::forced_import(
|
||||
db,
|
||||
"price_2w_choppiness_index",
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{DateIndex, Dollars, StoredF32};
|
||||
use brk_types::{DateIndex, StoredF32};
|
||||
use vecdb::{EagerVec, PcoVec};
|
||||
|
||||
use crate::internal::ComputedFromDateLast;
|
||||
use crate::internal::{ComputedFromDateLast, Price};
|
||||
|
||||
/// Price range and choppiness metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub price_1w_min: ComputedFromDateLast<Dollars>,
|
||||
pub price_1w_max: ComputedFromDateLast<Dollars>,
|
||||
pub price_2w_min: ComputedFromDateLast<Dollars>,
|
||||
pub price_2w_max: ComputedFromDateLast<Dollars>,
|
||||
pub price_1m_min: ComputedFromDateLast<Dollars>,
|
||||
pub price_1m_max: ComputedFromDateLast<Dollars>,
|
||||
pub price_1y_min: ComputedFromDateLast<Dollars>,
|
||||
pub price_1y_max: ComputedFromDateLast<Dollars>,
|
||||
pub price_1w_min: Price,
|
||||
pub price_1w_max: Price,
|
||||
pub price_2w_min: Price,
|
||||
pub price_2w_max: Price,
|
||||
pub price_1m_min: Price,
|
||||
pub price_1m_max: Price,
|
||||
pub price_1y_min: Price,
|
||||
pub price_1y_max: Price,
|
||||
pub price_true_range: EagerVec<PcoVec<DateIndex, StoredF32>>,
|
||||
pub price_true_range_2w_sum: EagerVec<PcoVec<DateIndex, StoredF32>>,
|
||||
pub price_2w_choppiness_index: ComputedFromDateLast<StoredF32>,
|
||||
|
||||
Reference in New Issue
Block a user