diff --git a/crates/brk_bindgen/src/analysis/tree.rs b/crates/brk_bindgen/src/analysis/tree.rs index be1b34604..5502b9631 100644 --- a/crates/brk_bindgen/src/analysis/tree.rs +++ b/crates/brk_bindgen/src/analysis/tree.rs @@ -513,10 +513,10 @@ mod tests { #[test] fn test_get_pattern_instance_base_suffix_mode_price_ago() { - // Simulates price_ago pattern: price_1d_ago, price_1w_ago, price_10y_ago + // Simulates price_ago pattern: price_24h_ago, price_1w_ago, price_10y_ago // Common prefix is "price_", so this is suffix mode let tree = make_branch(vec![ - ("_1d", make_leaf("price_1d_ago")), + ("_24h", make_leaf("price_24h_ago")), ("_1w", make_leaf("price_1w_ago")), ("_1m", make_leaf("price_1m_ago")), ("_10y", make_leaf("price_10y_ago")), @@ -524,16 +524,16 @@ mod tests { let result = get_pattern_instance_base(&tree); assert_eq!(result.base, "price"); - assert!(result.is_suffix_mode); // Suffix mode: _m(base, "1d_ago") + assert!(result.is_suffix_mode); // Suffix mode: _m(base, "24h_ago") assert!(!result.has_outlier); } #[test] fn test_get_pattern_instance_base_prefix_mode_price_returns() { - // Simulates price_returns pattern: 1d_price_returns, 1w_price_returns, 10y_price_returns + // Simulates price_returns pattern: 24h_price_returns, 1w_price_returns, 10y_price_returns // Common suffix is "_price_returns", so this is prefix mode let tree = make_branch(vec![ - ("_1d", make_leaf("1d_price_returns")), + ("_24h", make_leaf("24h_price_returns")), ("_1w", make_leaf("1w_price_returns")), ("_1m", make_leaf("1m_price_returns")), ("_10y", make_leaf("10y_price_returns")), @@ -541,7 +541,7 @@ mod tests { let result = get_pattern_instance_base(&tree); assert_eq!(result.base, "price_returns"); - assert!(!result.is_suffix_mode); // Prefix mode: _p("1d_", base) + assert!(!result.is_suffix_mode); // Prefix mode: _p("24h_", base) assert!(!result.has_outlier); } diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index d0f7a7d96..dd026ad1f 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -2863,28 +2863,6 @@ impl InvestedMaxMinPercentilesSpotPattern { } } -/// Pattern struct for repeated tree structure. -pub struct CloseHighLowOpenPricePattern { - pub close: MetricPattern2, - pub high: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern, - pub low: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern, - pub open: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern, - pub price: MetricPattern20, -} - -impl CloseHighLowOpenPricePattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - close: MetricPattern2::new(client.clone(), _m(&acc, "close")), - high: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern::new(client.clone(), _m(&acc, "high")), - low: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern::new(client.clone(), _m(&acc, "low")), - open: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern::new(client.clone(), _m(&acc, "open")), - price: MetricPattern20::new(client.clone(), acc.clone()), - } - } -} - /// Pattern struct for repeated tree structure. pub struct _1y24h30d7dPattern2 { pub _1y: BtcSatsUsdPattern, @@ -3055,6 +3033,24 @@ impl BtcSatsUsdPattern { } } +/// Pattern struct for repeated tree structure. +pub struct CentsSatsUsdPattern { + pub cents: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern, + pub sats: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern, + pub usd: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern, +} + +impl CentsSatsUsdPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + cents: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern::new(client.clone(), _m(&acc, "cents")), + sats: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern::new(client.clone(), _m(&acc, "sats")), + usd: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern::new(client.clone(), acc.clone()), + } + } +} + /// Pattern struct for repeated tree structure. pub struct HistogramLineSignalPattern { pub histogram: MetricPattern1, @@ -5973,17 +5969,70 @@ impl MetricsTree_Pools_Vecs { /// Metrics tree node. pub struct MetricsTree_Prices { - pub cents: CloseHighLowOpenPricePattern, - pub usd: CloseHighLowOpenPricePattern, - pub sats: CloseHighLowOpenPricePattern, + pub split: MetricsTree_Prices_Split, + pub ohlc: CentsSatsUsdPattern, + pub price: MetricsTree_Prices_Price, } impl MetricsTree_Prices { pub fn new(client: Arc, base_path: String) -> Self { Self { - cents: CloseHighLowOpenPricePattern::new(client.clone(), "price_cents".to_string()), - usd: CloseHighLowOpenPricePattern::new(client.clone(), "price_usd".to_string()), - sats: CloseHighLowOpenPricePattern::new(client.clone(), "price_sats".to_string()), + split: MetricsTree_Prices_Split::new(client.clone(), format!("{base_path}_split")), + ohlc: CentsSatsUsdPattern::new(client.clone(), "price_ohlc".to_string()), + price: MetricsTree_Prices_Price::new(client.clone(), format!("{base_path}_price")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Prices_Split { + pub open: CentsSatsUsdPattern, + pub high: CentsSatsUsdPattern, + pub low: CentsSatsUsdPattern, + pub close: MetricsTree_Prices_Split_Close, +} + +impl MetricsTree_Prices_Split { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + open: CentsSatsUsdPattern::new(client.clone(), "price_open".to_string()), + high: CentsSatsUsdPattern::new(client.clone(), "price_high".to_string()), + low: CentsSatsUsdPattern::new(client.clone(), "price_low".to_string()), + close: MetricsTree_Prices_Split_Close::new(client.clone(), format!("{base_path}_close")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Prices_Split_Close { + pub cents: MetricPattern2, + pub usd: MetricPattern2, + pub sats: MetricPattern2, +} + +impl MetricsTree_Prices_Split_Close { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + cents: MetricPattern2::new(client.clone(), "price_close_cents".to_string()), + usd: MetricPattern2::new(client.clone(), "price_close".to_string()), + sats: MetricPattern2::new(client.clone(), "price_close_sats".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Prices_Price { + pub cents: MetricPattern20, + pub usd: MetricPattern20, + pub sats: MetricPattern20, +} + +impl MetricsTree_Prices_Price { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + cents: MetricPattern20::new(client.clone(), "price_cents".to_string()), + usd: MetricPattern20::new(client.clone(), "price".to_string()), + sats: MetricPattern20::new(client.clone(), "price_sats".to_string()), } } } diff --git a/crates/brk_computer/src/market/indicators/rsi.rs b/crates/brk_computer/src/market/indicators/rsi.rs index 7442e9cb9..1ea9d9a29 100644 --- a/crates/brk_computer/src/market/indicators/rsi.rs +++ b/crates/brk_computer/src/market/indicators/rsi.rs @@ -19,7 +19,7 @@ pub(super) fn compute( starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { - let source_version = returns.price_returns._1d.height.version(); + let source_version = returns.price_returns._24h.height.version(); let vecs = [ &mut chain.gains.height, diff --git a/crates/brk_computer/src/market/indicators/timeframe.rs b/crates/brk_computer/src/market/indicators/timeframe.rs index 1a5bdf0e3..898426a83 100644 --- a/crates/brk_computer/src/market/indicators/timeframe.rs +++ b/crates/brk_computer/src/market/indicators/timeframe.rs @@ -5,7 +5,7 @@ use crate::{market::returns::Vecs as ReturnsVecs, prices}; pub(super) fn collect_returns(tf: &str, returns: &ReturnsVecs) -> Vec { let data: Vec = match tf { - "1d" => returns.price_returns._1d.day1.collect_or_default(), + "1d" => returns.price_returns._24h.day1.collect_or_default(), "1w" => returns.price_returns._1w.week1.collect_or_default(), "1m" => returns.price_returns._1m.month1.collect_or_default(), "1y" => returns.price_returns._1y.year1.collect_or_default(), diff --git a/crates/brk_computer/src/market/lookback/by_period.rs b/crates/brk_computer/src/market/lookback/by_period.rs index 2cc8bf4fb..a43df7a16 100644 --- a/crates/brk_computer/src/market/lookback/by_period.rs +++ b/crates/brk_computer/src/market/lookback/by_period.rs @@ -2,9 +2,9 @@ use brk_traversable::Traversable; use crate::market::dca::ByDcaPeriod; -/// Lookback period days (includes 1d, unlike DCA) +/// Lookback period days (includes 24h, unlike DCA) pub const LOOKBACK_PERIOD_DAYS: ByLookbackPeriod = ByLookbackPeriod { - _1d: 1, + _24h: 1, _1w: 7, _1m: 30, _3m: 3 * 30, @@ -21,7 +21,7 @@ pub const LOOKBACK_PERIOD_DAYS: ByLookbackPeriod = ByLookbackPeriod { /// Lookback period names pub const LOOKBACK_PERIOD_NAMES: ByLookbackPeriod<&'static str> = ByLookbackPeriod { - _1d: "1d", + _24h: "24h", _1w: "1w", _1m: "1m", _3m: "3m", @@ -36,10 +36,10 @@ pub const LOOKBACK_PERIOD_NAMES: ByLookbackPeriod<&'static str> = ByLookbackPeri _10y: "10y", }; -/// Generic wrapper for lookback period-based data (includes 1d) +/// Generic wrapper for lookback period-based data (includes 24h) #[derive(Clone, Default, Traversable)] pub struct ByLookbackPeriod { - pub _1d: T, + pub _24h: T, pub _1w: T, pub _1m: T, pub _3m: T, @@ -62,7 +62,7 @@ impl ByLookbackPeriod { let n = LOOKBACK_PERIOD_NAMES; let d = LOOKBACK_PERIOD_DAYS; Ok(Self { - _1d: create(n._1d, d._1d)?, + _24h: create(n._24h, d._24h)?, _1w: create(n._1w, d._1w)?, _1m: create(n._1m, d._1m)?, _3m: create(n._3m, d._3m)?, @@ -81,7 +81,7 @@ impl ByLookbackPeriod { pub(crate) fn iter_with_days(&self) -> impl Iterator { let d = LOOKBACK_PERIOD_DAYS; [ - (&self._1d, d._1d), + (&self._24h, d._24h), (&self._1w, d._1w), (&self._1m, d._1m), (&self._3m, d._3m), @@ -101,7 +101,7 @@ impl ByLookbackPeriod { pub(crate) fn iter_mut_with_days(&mut self) -> impl Iterator { let d = LOOKBACK_PERIOD_DAYS; [ - (&mut self._1d, d._1d), + (&mut self._24h, d._24h), (&mut self._1w, d._1w), (&mut self._1m, d._1m), (&mut self._3m, d._3m), @@ -118,7 +118,7 @@ impl ByLookbackPeriod { .into_iter() } - /// Get the DCA-matching subset (excludes 1d) + /// Get the DCA-matching subset (excludes 24h) pub(crate) fn as_dca_period(&self) -> ByDcaPeriod<&T> { ByDcaPeriod { _1w: &self._1w, diff --git a/crates/brk_computer/src/market/returns/compute.rs b/crates/brk_computer/src/market/returns/compute.rs index 11da8cbc3..70b5288e7 100644 --- a/crates/brk_computer/src/market/returns/compute.rs +++ b/crates/brk_computer/src/market/returns/compute.rs @@ -55,19 +55,19 @@ impl Vecs { )?; } - let _1d_price_returns_height = &self.price_returns._1d.height; + let _24h_price_returns_height = &self.price_returns._24h.height; self._1d_returns_1w_sd - .compute_all(blocks, starting_indexes, exit, _1d_price_returns_height)?; + .compute_all(blocks, starting_indexes, exit, _24h_price_returns_height)?; self._1d_returns_1m_sd - .compute_all(blocks, starting_indexes, exit, _1d_price_returns_height)?; + .compute_all(blocks, starting_indexes, exit, _24h_price_returns_height)?; self._1d_returns_1y_sd - .compute_all(blocks, starting_indexes, exit, _1d_price_returns_height)?; + .compute_all(blocks, starting_indexes, exit, _24h_price_returns_height)?; // Downside returns: min(return, 0) self.downside_returns.compute_transform( starting_indexes.height, - _1d_price_returns_height, + _24h_price_returns_height, |(i, ret, ..)| (i, StoredF32::from((*ret).min(0.0))), exit, )?; diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index 1580a0b34..13d9a98f9 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -186,6 +186,11 @@ * * @typedef {number} CentsSquaredSats */ +/** + * Closing price value for a time period + * + * @typedef {Cents} Close + */ /** * Cohort identifier for cost basis distribution. * @@ -363,6 +368,11 @@ * * @typedef {string} Hex */ +/** + * Highest price value for a time period + * + * @typedef {Cents} High + */ /** @typedef {number} Hour1 */ /** @typedef {number} Hour12 */ /** @typedef {number} Hour4 */ @@ -388,6 +398,11 @@ * @typedef {Object} LimitParam * @property {Limit=} limit */ +/** + * Lowest price value for a time period + * + * @typedef {Cents} Low + */ /** * Block info in a mempool.space like format for fee estimation. * @@ -473,7 +488,39 @@ /** @typedef {number} Month1 */ /** @typedef {number} Month3 */ /** @typedef {number} Month6 */ +/** + * OHLC (Open, High, Low, Close) data in cents + * + * @typedef {Object} OHLCCents + * @property {Open} open + * @property {High} high + * @property {Low} low + * @property {Close} close + */ +/** + * OHLC (Open, High, Low, Close) data in dollars + * + * @typedef {Object} OHLCDollars + * @property {Open} open + * @property {High} high + * @property {Low} low + * @property {Close} close + */ +/** + * OHLC (Open, High, Low, Close) data in satoshis + * + * @typedef {Object} OHLCSats + * @property {Open} open + * @property {High} high + * @property {Low} low + * @property {Close} close + */ /** @typedef {TypeIndex} OpReturnIndex */ +/** + * Opening price value for a time period + * + * @typedef {Cents} Open + */ /** @typedef {number} OutPoint */ /** * Type (P2PKH, P2WPKH, P2SH, P2TR, etc.) @@ -3507,33 +3554,6 @@ function createInvestedMaxMinPercentilesSpotPattern(client, acc) { }; } -/** - * @template T - * @typedef {Object} CloseHighLowOpenPricePattern - * @property {MetricPattern2} close - * @property {Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern} high - * @property {Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern} low - * @property {Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern} open - * @property {MetricPattern20} price - */ - -/** - * Create a CloseHighLowOpenPricePattern pattern node - * @template T - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {CloseHighLowOpenPricePattern} - */ -function createCloseHighLowOpenPricePattern(client, acc) { - return { - close: createMetricPattern2(client, _m(acc, 'close')), - high: createDay1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'high')), - low: createDay1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'low')), - open: createDay1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'open')), - price: createMetricPattern20(client, acc), - }; -} - /** * @typedef {Object} _1y24h30d7dPattern2 * @property {BtcSatsUsdPattern} _1y @@ -3735,6 +3755,27 @@ function createBtcSatsUsdPattern(client, acc) { }; } +/** + * @typedef {Object} CentsSatsUsdPattern + * @property {Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern} cents + * @property {Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern} sats + * @property {Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern} usd + */ + +/** + * Create a CentsSatsUsdPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {CentsSatsUsdPattern} + */ +function createCentsSatsUsdPattern(client, acc) { + return { + cents: createDay1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'cents')), + sats: createDay1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'sats')), + usd: createDay1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, acc), + }; +} + /** * @typedef {Object} HistogramLineSignalPattern * @property {MetricPattern1} histogram @@ -5178,9 +5219,31 @@ function createRatioPattern2(client, acc) { /** * @typedef {Object} MetricsTree_Prices - * @property {CloseHighLowOpenPricePattern} cents - * @property {CloseHighLowOpenPricePattern} usd - * @property {CloseHighLowOpenPricePattern} sats + * @property {MetricsTree_Prices_Split} split + * @property {CentsSatsUsdPattern} ohlc + * @property {MetricsTree_Prices_Price} price + */ + +/** + * @typedef {Object} MetricsTree_Prices_Split + * @property {CentsSatsUsdPattern} open + * @property {CentsSatsUsdPattern} high + * @property {CentsSatsUsdPattern} low + * @property {MetricsTree_Prices_Split_Close} close + */ + +/** + * @typedef {Object} MetricsTree_Prices_Split_Close + * @property {MetricPattern2} cents + * @property {MetricPattern2} usd + * @property {MetricPattern2} sats + */ + +/** + * @typedef {Object} MetricsTree_Prices_Price + * @property {MetricPattern20} cents + * @property {MetricPattern20} usd + * @property {MetricPattern20} sats */ /** @@ -7449,9 +7512,22 @@ class BrkClient extends BrkClientBase { }, }, prices: { - cents: createCloseHighLowOpenPricePattern(this, 'price_cents'), - usd: createCloseHighLowOpenPricePattern(this, 'price_usd'), - sats: createCloseHighLowOpenPricePattern(this, 'price_sats'), + split: { + open: createCentsSatsUsdPattern(this, 'price_open'), + high: createCentsSatsUsdPattern(this, 'price_high'), + low: createCentsSatsUsdPattern(this, 'price_low'), + close: { + cents: createMetricPattern2(this, 'price_close_cents'), + usd: createMetricPattern2(this, 'price_close'), + sats: createMetricPattern2(this, 'price_close_sats'), + }, + }, + ohlc: createCentsSatsUsdPattern(this, 'price_ohlc'), + price: { + cents: createMetricPattern20(this, 'price_cents'), + usd: createMetricPattern20(this, 'price'), + sats: createMetricPattern20(this, 'price_sats'), + }, }, distribution: { supplyState: createMetricPattern20(this, 'supply_state'), diff --git a/packages/brk_client/brk_client/__init__.py b/packages/brk_client/brk_client/__init__.py index c98a3542a..a35f107d7 100644 --- a/packages/brk_client/brk_client/__init__.py +++ b/packages/brk_client/brk_client/__init__.py @@ -50,6 +50,8 @@ CentsSats = int # Used for precise accumulation of investor cap values: Σ(price² × sats). # investor_price = investor_cap_raw / realized_cap_raw CentsSquaredSats = int +# Closing price value for a time period +Close = Cents # Cohort identifier for cost basis distribution. Cohort = str # Bucket type for cost basis aggregation. @@ -78,9 +80,13 @@ FundedAddressIndex = TypeIndex HalvingEpoch = int # Hex-encoded string Hex = str +# Highest price value for a time period +High = Cents Hour1 = int Hour12 = int Hour4 = int +# Lowest price value for a time period +Low = Cents # Virtual size in vbytes (weight / 4, rounded up) VSize = int # Metric name @@ -100,6 +106,8 @@ Minute5 = int Month1 = int Month3 = int Month6 = int +# Opening price value for a time period +Open = Cents OpReturnIndex = TypeIndex OutPoint = int # Type (P2PKH, P2WPKH, P2SH, P2TR, etc.) @@ -667,6 +675,33 @@ class MetricWithIndex(TypedDict): metric: Metric index: Index +class OHLCCents(TypedDict): + """ + OHLC (Open, High, Low, Close) data in cents + """ + open: Open + high: High + low: Low + close: Close + +class OHLCDollars(TypedDict): + """ + OHLC (Open, High, Low, Close) data in dollars + """ + open: Open + high: High + low: Low + close: Close + +class OHLCSats(TypedDict): + """ + OHLC (Open, High, Low, Close) data in satoshis + """ + open: Open + high: High + low: Low + close: Close + class PaginatedMetrics(TypedDict): """ A paginated list of available metric names (1000 per page) @@ -2991,17 +3026,6 @@ class InvestedMaxMinPercentilesSpotPattern: self.spot_cost_basis_percentile: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'spot_cost_basis_percentile')) self.spot_invested_capital_percentile: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'spot_invested_capital_percentile')) -class CloseHighLowOpenPricePattern(Generic[T]): - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.close: MetricPattern2[T] = MetricPattern2(client, _m(acc, 'close')) - self.high: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern[T] = Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'high')) - self.low: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern[T] = Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'low')) - self.open: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern[T] = Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'open')) - self.price: MetricPattern20[T] = MetricPattern20(client, acc) - class _1y24h30d7dPattern2: """Pattern struct for repeated tree structure.""" @@ -3087,6 +3111,15 @@ class BtcSatsUsdPattern: self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) +class CentsSatsUsdPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.cents: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern[OHLCCents] = Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'cents')) + self.sats: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern[OHLCSats] = Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, _m(acc, 'sats')) + self.usd: Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern[OHLCDollars] = Day1Day3DifficultyepochHalvingepochHour1Hour12Hour4Minute1Minute10Minute30Minute5Month1Month3Month6Week1Year1Year10Pattern(client, acc) + class HistogramLineSignalPattern: """Pattern struct for repeated tree structure.""" @@ -4476,13 +4509,38 @@ class MetricsTree_Pools: self.height_to_pool: MetricPattern20[PoolSlug] = MetricPattern20(client, 'pool') self.vecs: MetricsTree_Pools_Vecs = MetricsTree_Pools_Vecs(client) +class MetricsTree_Prices_Split_Close: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.cents: MetricPattern2[Cents] = MetricPattern2(client, 'price_close_cents') + self.usd: MetricPattern2[Dollars] = MetricPattern2(client, 'price_close') + self.sats: MetricPattern2[Sats] = MetricPattern2(client, 'price_close_sats') + +class MetricsTree_Prices_Split: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.open: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'price_open') + self.high: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'price_high') + self.low: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'price_low') + self.close: MetricsTree_Prices_Split_Close = MetricsTree_Prices_Split_Close(client) + +class MetricsTree_Prices_Price: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.cents: MetricPattern20[Cents] = MetricPattern20(client, 'price_cents') + self.usd: MetricPattern20[Dollars] = MetricPattern20(client, 'price') + self.sats: MetricPattern20[Sats] = MetricPattern20(client, 'price_sats') + class MetricsTree_Prices: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.cents: CloseHighLowOpenPricePattern[Cents] = CloseHighLowOpenPricePattern(client, 'price_cents') - self.usd: CloseHighLowOpenPricePattern[Dollars] = CloseHighLowOpenPricePattern(client, 'price_usd') - self.sats: CloseHighLowOpenPricePattern[Sats] = CloseHighLowOpenPricePattern(client, 'price_sats') + self.split: MetricsTree_Prices_Split = MetricsTree_Prices_Split(client) + self.ohlc: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'price_ohlc') + self.price: MetricsTree_Prices_Price = MetricsTree_Prices_Price(client) class MetricsTree_Distribution_AnyAddressIndexes: """Metrics tree node.""" diff --git a/website/scripts/options/market.js b/website/scripts/options/market.js index e6ad162a8..41382617f 100644 --- a/website/scripts/options/market.js +++ b/website/scripts/options/market.js @@ -197,7 +197,7 @@ export function createMarketSection() { } = market; const shortPeriodsBase = [ - { id: "1d", returns: returns.priceReturns._1d, lookback: lookback._1d }, + { id: "24h", returns: returns.priceReturns._24h, lookback: lookback._24h }, { id: "1w", returns: returns.priceReturns._1w, lookback: lookback._1w }, { id: "1m", returns: returns.priceReturns._1m, lookback: lookback._1m }, { diff --git a/website/scripts/options/utils.js b/website/scripts/options/utils.js index 936173d85..3ccbccc61 100644 --- a/website/scripts/options/utils.js +++ b/website/scripts/options/utils.js @@ -9,6 +9,8 @@ export function periodIdToName(id, compoundAdjective) { const num = parseInt(id); const s = compoundAdjective || num === 1 ? "" : "s"; switch (id.slice(-1)) { + case "h": + return `${num} hour${s}`; case "d": return `${num} day${s}`; case "w":