Files
brk/crates/brk_oracle/src/config.rs
T
2026-05-24 18:40:35 +02:00

65 lines
2.3 KiB
Rust

/// First height the oracle computes on-chain, with the slow cold-start EMA
/// ([`slow`](Config::slow)). Below it, prices come from [`PRICES`](crate::PRICES).
pub const START_HEIGHT_SLOW: usize = 340_000;
/// Height where the oracle switches slow -> fast EMA ([`default`](Config::default)).
/// The regimes are complementary: slow resists the round-USD half-price drift
/// that locks fast below here, while fast tracks the 2018-2019 crashes that lock
/// slow.
pub const START_HEIGHT_FAST: usize = 508_000;
#[derive(Clone)]
pub struct Config {
/// EMA decay: 2/(N+1) where N is span in blocks. 2/7 = 6-block span.
pub alpha: f64,
/// Ring buffer depth. 12 blocks for deterministic convergence at any start height.
pub window_size: usize,
/// Search window bins below/above previous estimate. Asymmetric for log-scale.
pub search_below: usize,
pub search_above: usize,
/// Weight of the adaptive shape-anchoring restoring force added to the
/// stencil score. `0.0` disables it (mature regime, where the fast EMA
/// tracks real moves the shape term would resist). The slow cold-start uses
/// a positive weight to resist round-USD octave aliasing in the thin early
/// output mix.
pub shape_weight: f64,
}
impl Default for Config {
fn default() -> Self {
Self {
alpha: 2.0 / 7.0,
window_size: 12,
search_below: 12,
search_above: 11,
shape_weight: 0.0,
}
}
}
impl Config {
/// Cold-start config below [`START_HEIGHT_FAST`]: a slow EMA
/// (span ~19) that resists the round-USD half-price drift the fast default
/// octave-locks onto in the thin pre-2018 output mix. Window grows to 40 to
/// hold the decay, and a shape-anchoring restoring force (`shape_weight`)
/// pulls the pick toward the octave whose arm-shape looks like real payments.
pub fn slow() -> Self {
Self {
alpha: 0.10,
window_size: 40,
shape_weight: 8.0,
..Self::default()
}
}
/// Config for `height`: [`slow`](Self::slow) below [`START_HEIGHT_FAST`], else
/// [`default`](Self::default).
pub fn for_height(height: usize) -> Self {
if height < START_HEIGHT_FAST {
Self::slow()
} else {
Self::default()
}
}
}