mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
@@ -5160,7 +5160,7 @@ pub struct SeriesTree_Indicators {
|
||||
pub dormancy: SeriesTree_Indicators_Dormancy,
|
||||
pub stock_to_flow: SeriesPattern1<StoredF32>,
|
||||
pub seller_exhaustion: SeriesPattern1<StoredF32>,
|
||||
pub thermometer: SeriesTree_Indicators_Thermometer,
|
||||
pub realized_envelope: SeriesTree_Indicators_RealizedEnvelope,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indicators {
|
||||
@@ -5176,7 +5176,7 @@ impl SeriesTree_Indicators {
|
||||
dormancy: SeriesTree_Indicators_Dormancy::new(client.clone(), format!("{base_path}_dormancy")),
|
||||
stock_to_flow: SeriesPattern1::new(client.clone(), "stock_to_flow".to_string()),
|
||||
seller_exhaustion: SeriesPattern1::new(client.clone(), "seller_exhaustion".to_string()),
|
||||
thermometer: SeriesTree_Indicators_Thermometer::new(client.clone(), format!("{base_path}_thermometer")),
|
||||
realized_envelope: SeriesTree_Indicators_RealizedEnvelope::new(client.clone(), format!("{base_path}_realized_envelope")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5197,7 +5197,7 @@ impl SeriesTree_Indicators_Dormancy {
|
||||
}
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indicators_Thermometer {
|
||||
pub struct SeriesTree_Indicators_RealizedEnvelope {
|
||||
pub pct0_5: CentsSatsUsdPattern,
|
||||
pub pct1: CentsSatsUsdPattern,
|
||||
pub pct2: CentsSatsUsdPattern,
|
||||
@@ -5206,23 +5206,23 @@ pub struct SeriesTree_Indicators_Thermometer {
|
||||
pub pct98: CentsSatsUsdPattern,
|
||||
pub pct99: CentsSatsUsdPattern,
|
||||
pub pct99_5: CentsSatsUsdPattern,
|
||||
pub zone: SeriesPattern1<StoredI8>,
|
||||
pub index: SeriesPattern1<StoredI8>,
|
||||
pub score: SeriesPattern1<StoredI8>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indicators_Thermometer {
|
||||
impl SeriesTree_Indicators_RealizedEnvelope {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
pct0_5: CentsSatsUsdPattern::new(client.clone(), "thermometer_pct0_5".to_string()),
|
||||
pct1: CentsSatsUsdPattern::new(client.clone(), "thermometer_pct01".to_string()),
|
||||
pct2: CentsSatsUsdPattern::new(client.clone(), "thermometer_pct02".to_string()),
|
||||
pct5: CentsSatsUsdPattern::new(client.clone(), "thermometer_pct05".to_string()),
|
||||
pct95: CentsSatsUsdPattern::new(client.clone(), "thermometer_pct95".to_string()),
|
||||
pct98: CentsSatsUsdPattern::new(client.clone(), "thermometer_pct98".to_string()),
|
||||
pct99: CentsSatsUsdPattern::new(client.clone(), "thermometer_pct99".to_string()),
|
||||
pct99_5: CentsSatsUsdPattern::new(client.clone(), "thermometer_pct99_5".to_string()),
|
||||
zone: SeriesPattern1::new(client.clone(), "thermometer_zone".to_string()),
|
||||
score: SeriesPattern1::new(client.clone(), "thermometer_score".to_string()),
|
||||
pct0_5: CentsSatsUsdPattern::new(client.clone(), "realized_envelope_pct0_5".to_string()),
|
||||
pct1: CentsSatsUsdPattern::new(client.clone(), "realized_envelope_pct01".to_string()),
|
||||
pct2: CentsSatsUsdPattern::new(client.clone(), "realized_envelope_pct02".to_string()),
|
||||
pct5: CentsSatsUsdPattern::new(client.clone(), "realized_envelope_pct05".to_string()),
|
||||
pct95: CentsSatsUsdPattern::new(client.clone(), "realized_envelope_pct95".to_string()),
|
||||
pct98: CentsSatsUsdPattern::new(client.clone(), "realized_envelope_pct98".to_string()),
|
||||
pct99: CentsSatsUsdPattern::new(client.clone(), "realized_envelope_pct99".to_string()),
|
||||
pct99_5: CentsSatsUsdPattern::new(client.clone(), "realized_envelope_pct99_5".to_string()),
|
||||
index: SeriesPattern1::new(client.clone(), "realized_envelope_index".to_string()),
|
||||
score: SeriesPattern1::new(client.clone(), "realized_envelope_score".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::path::Path;
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
|
||||
use super::{Vecs, thermometer::Thermometer};
|
||||
use super::{Vecs, realized_envelope::RealizedEnvelope};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{PerBlock, PercentPerBlock, RatioPerBlock, db_utils::{finalize_db, open_db}},
|
||||
@@ -38,7 +38,7 @@ impl Vecs {
|
||||
let seller_exhaustion =
|
||||
PerBlock::forced_import(&db, "seller_exhaustion", v, indexes)?;
|
||||
|
||||
let thermometer = Thermometer::forced_import(&db, v, indexes)?;
|
||||
let realized_envelope = RealizedEnvelope::forced_import(&db, v, indexes)?;
|
||||
|
||||
let this = Self {
|
||||
db,
|
||||
@@ -52,7 +52,7 @@ impl Vecs {
|
||||
dormancy,
|
||||
stock_to_flow,
|
||||
seller_exhaustion,
|
||||
thermometer,
|
||||
realized_envelope,
|
||||
};
|
||||
finalize_db(&this.db, &this)?;
|
||||
Ok(this)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mod compute;
|
||||
mod gini;
|
||||
mod import;
|
||||
pub mod thermometer;
|
||||
pub mod realized_envelope;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Thermometer<M: StorageMode = Rw> {
|
||||
pub struct RealizedEnvelope<M: StorageMode = Rw> {
|
||||
pub pct0_5: Price<PerBlock<Cents, M>>,
|
||||
pub pct1: Price<PerBlock<Cents, M>>,
|
||||
pub pct2: Price<PerBlock<Cents, M>>,
|
||||
@@ -21,13 +21,13 @@ pub struct Thermometer<M: StorageMode = Rw> {
|
||||
pub pct98: Price<PerBlock<Cents, M>>,
|
||||
pub pct99: Price<PerBlock<Cents, M>>,
|
||||
pub pct99_5: Price<PerBlock<Cents, M>>,
|
||||
pub zone: PerBlock<StoredI8, M>,
|
||||
pub index: PerBlock<StoredI8, M>,
|
||||
pub score: PerBlock<StoredI8, M>,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::new(2);
|
||||
const VERSION: Version = Version::new(3);
|
||||
|
||||
impl Thermometer {
|
||||
impl RealizedEnvelope {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
@@ -35,16 +35,16 @@ impl Thermometer {
|
||||
) -> Result<Self> {
|
||||
let v = version + VERSION;
|
||||
Ok(Self {
|
||||
pct0_5: Price::forced_import(db, "thermometer_pct0_5", v, indexes)?,
|
||||
pct1: Price::forced_import(db, "thermometer_pct01", v, indexes)?,
|
||||
pct2: Price::forced_import(db, "thermometer_pct02", v, indexes)?,
|
||||
pct5: Price::forced_import(db, "thermometer_pct05", v, indexes)?,
|
||||
pct95: Price::forced_import(db, "thermometer_pct95", v, indexes)?,
|
||||
pct98: Price::forced_import(db, "thermometer_pct98", v, indexes)?,
|
||||
pct99: Price::forced_import(db, "thermometer_pct99", v, indexes)?,
|
||||
pct99_5: Price::forced_import(db, "thermometer_pct99_5", v, indexes)?,
|
||||
zone: PerBlock::forced_import(db, "thermometer_zone", v, indexes)?,
|
||||
score: PerBlock::forced_import(db, "thermometer_score", v, indexes)?,
|
||||
pct0_5: Price::forced_import(db, "realized_envelope_pct0_5", v, indexes)?,
|
||||
pct1: Price::forced_import(db, "realized_envelope_pct01", v, indexes)?,
|
||||
pct2: Price::forced_import(db, "realized_envelope_pct02", v, indexes)?,
|
||||
pct5: Price::forced_import(db, "realized_envelope_pct05", v, indexes)?,
|
||||
pct95: Price::forced_import(db, "realized_envelope_pct95", v, indexes)?,
|
||||
pct98: Price::forced_import(db, "realized_envelope_pct98", v, indexes)?,
|
||||
pct99: Price::forced_import(db, "realized_envelope_pct99", v, indexes)?,
|
||||
pct99_5: Price::forced_import(db, "realized_envelope_pct99_5", v, indexes)?,
|
||||
index: PerBlock::forced_import(db, "realized_envelope_index", v, indexes)?,
|
||||
score: PerBlock::forced_import(db, "realized_envelope_score", v, indexes)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ impl Thermometer {
|
||||
let spot = &prices.spot.cents.height;
|
||||
|
||||
// Zone: spot vs own envelope bands (-4 to +4)
|
||||
self.compute_zone(spot, starting_indexes, exit)?;
|
||||
self.compute_index(spot, starting_indexes, exit)?;
|
||||
|
||||
// Temperature: per-model band crossings (-40 to +40)
|
||||
self.compute_score(&models, spot, starting_indexes, exit)?;
|
||||
@@ -104,7 +104,7 @@ impl Thermometer {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compute_zone(
|
||||
fn compute_index(
|
||||
&mut self,
|
||||
spot: &EagerVec<PcoVec<Height, Cents>>,
|
||||
starting_indexes: &Indexes,
|
||||
@@ -123,10 +123,10 @@ impl Thermometer {
|
||||
|
||||
let dep_version: Version = bands.iter().map(|b| b.version()).sum::<Version>() + spot.version();
|
||||
|
||||
self.zone.height.validate_computed_version_or_reset(dep_version)?;
|
||||
self.zone.height.truncate_if_needed(starting_indexes.height)?;
|
||||
self.index.height.validate_computed_version_or_reset(dep_version)?;
|
||||
self.index.height.truncate_if_needed(starting_indexes.height)?;
|
||||
|
||||
self.zone.height.repeat_until_complete(exit, |vec| {
|
||||
self.index.height.repeat_until_complete(exit, |vec| {
|
||||
let skip = vec.len();
|
||||
let source_end = bands.iter().map(|b| b.len()).min().unwrap().min(spot.len());
|
||||
let end = vec.batch_end(source_end);
|
||||
@@ -2,7 +2,7 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{BasisPoints16, BasisPoints32, StoredF32};
|
||||
use vecdb::{Database, Rw, StorageMode};
|
||||
|
||||
use super::thermometer::Thermometer;
|
||||
use super::realized_envelope::RealizedEnvelope;
|
||||
use crate::internal::{PerBlock, PercentPerBlock, RatioPerBlock};
|
||||
|
||||
#[derive(Traversable)]
|
||||
@@ -25,5 +25,5 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub dormancy: DormancyVecs<M>,
|
||||
pub stock_to_flow: PerBlock<StoredF32, M>,
|
||||
pub seller_exhaustion: PerBlock<StoredF32, M>,
|
||||
pub thermometer: Thermometer<M>,
|
||||
pub realized_envelope: RealizedEnvelope<M>,
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ impl Computer {
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indicators.thermometer.compute(
|
||||
self.indicators.realized_envelope.compute(
|
||||
&self.distribution,
|
||||
&self.cointime,
|
||||
&self.prices,
|
||||
|
||||
@@ -5014,7 +5014,7 @@ function createTransferPattern(client, acc) {
|
||||
* @property {SeriesTree_Indicators_Dormancy} dormancy
|
||||
* @property {SeriesPattern1<StoredF32>} stockToFlow
|
||||
* @property {SeriesPattern1<StoredF32>} sellerExhaustion
|
||||
* @property {SeriesTree_Indicators_Thermometer} thermometer
|
||||
* @property {SeriesTree_Indicators_RealizedEnvelope} realizedEnvelope
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -5024,7 +5024,7 @@ function createTransferPattern(client, acc) {
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SeriesTree_Indicators_Thermometer
|
||||
* @typedef {Object} SeriesTree_Indicators_RealizedEnvelope
|
||||
* @property {CentsSatsUsdPattern} pct05
|
||||
* @property {CentsSatsUsdPattern} pct1
|
||||
* @property {CentsSatsUsdPattern} pct2
|
||||
@@ -5033,7 +5033,7 @@ function createTransferPattern(client, acc) {
|
||||
* @property {CentsSatsUsdPattern} pct98
|
||||
* @property {CentsSatsUsdPattern} pct99
|
||||
* @property {CentsSatsUsdPattern} pct995
|
||||
* @property {SeriesPattern1<StoredI8>} zone
|
||||
* @property {SeriesPattern1<StoredI8>} index
|
||||
* @property {SeriesPattern1<StoredI8>} score
|
||||
*/
|
||||
|
||||
@@ -8142,17 +8142,17 @@ class BrkClient extends BrkClientBase {
|
||||
},
|
||||
stockToFlow: createSeriesPattern1(this, 'stock_to_flow'),
|
||||
sellerExhaustion: createSeriesPattern1(this, 'seller_exhaustion'),
|
||||
thermometer: {
|
||||
pct05: createCentsSatsUsdPattern(this, 'thermometer_pct0_5'),
|
||||
pct1: createCentsSatsUsdPattern(this, 'thermometer_pct01'),
|
||||
pct2: createCentsSatsUsdPattern(this, 'thermometer_pct02'),
|
||||
pct5: createCentsSatsUsdPattern(this, 'thermometer_pct05'),
|
||||
pct95: createCentsSatsUsdPattern(this, 'thermometer_pct95'),
|
||||
pct98: createCentsSatsUsdPattern(this, 'thermometer_pct98'),
|
||||
pct99: createCentsSatsUsdPattern(this, 'thermometer_pct99'),
|
||||
pct995: createCentsSatsUsdPattern(this, 'thermometer_pct99_5'),
|
||||
zone: createSeriesPattern1(this, 'thermometer_zone'),
|
||||
score: createSeriesPattern1(this, 'thermometer_score'),
|
||||
realizedEnvelope: {
|
||||
pct05: createCentsSatsUsdPattern(this, 'realized_envelope_pct0_5'),
|
||||
pct1: createCentsSatsUsdPattern(this, 'realized_envelope_pct01'),
|
||||
pct2: createCentsSatsUsdPattern(this, 'realized_envelope_pct02'),
|
||||
pct5: createCentsSatsUsdPattern(this, 'realized_envelope_pct05'),
|
||||
pct95: createCentsSatsUsdPattern(this, 'realized_envelope_pct95'),
|
||||
pct98: createCentsSatsUsdPattern(this, 'realized_envelope_pct98'),
|
||||
pct99: createCentsSatsUsdPattern(this, 'realized_envelope_pct99'),
|
||||
pct995: createCentsSatsUsdPattern(this, 'realized_envelope_pct99_5'),
|
||||
index: createSeriesPattern1(this, 'realized_envelope_index'),
|
||||
score: createSeriesPattern1(this, 'realized_envelope_score'),
|
||||
},
|
||||
},
|
||||
investing: {
|
||||
|
||||
@@ -4189,20 +4189,20 @@ class SeriesTree_Indicators_Dormancy:
|
||||
self.supply_adjusted: SeriesPattern1[StoredF32] = SeriesPattern1(client, 'dormancy_supply_adjusted')
|
||||
self.flow: SeriesPattern1[StoredF32] = SeriesPattern1(client, 'dormancy_flow')
|
||||
|
||||
class SeriesTree_Indicators_Thermometer:
|
||||
class SeriesTree_Indicators_RealizedEnvelope:
|
||||
"""Series tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.pct0_5: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'thermometer_pct0_5')
|
||||
self.pct1: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'thermometer_pct01')
|
||||
self.pct2: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'thermometer_pct02')
|
||||
self.pct5: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'thermometer_pct05')
|
||||
self.pct95: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'thermometer_pct95')
|
||||
self.pct98: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'thermometer_pct98')
|
||||
self.pct99: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'thermometer_pct99')
|
||||
self.pct99_5: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'thermometer_pct99_5')
|
||||
self.zone: SeriesPattern1[StoredI8] = SeriesPattern1(client, 'thermometer_zone')
|
||||
self.score: SeriesPattern1[StoredI8] = SeriesPattern1(client, 'thermometer_score')
|
||||
self.pct0_5: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'realized_envelope_pct0_5')
|
||||
self.pct1: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'realized_envelope_pct01')
|
||||
self.pct2: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'realized_envelope_pct02')
|
||||
self.pct5: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'realized_envelope_pct05')
|
||||
self.pct95: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'realized_envelope_pct95')
|
||||
self.pct98: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'realized_envelope_pct98')
|
||||
self.pct99: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'realized_envelope_pct99')
|
||||
self.pct99_5: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'realized_envelope_pct99_5')
|
||||
self.index: SeriesPattern1[StoredI8] = SeriesPattern1(client, 'realized_envelope_index')
|
||||
self.score: SeriesPattern1[StoredI8] = SeriesPattern1(client, 'realized_envelope_score')
|
||||
|
||||
class SeriesTree_Indicators:
|
||||
"""Series tree node."""
|
||||
@@ -4218,7 +4218,7 @@ class SeriesTree_Indicators:
|
||||
self.dormancy: SeriesTree_Indicators_Dormancy = SeriesTree_Indicators_Dormancy(client)
|
||||
self.stock_to_flow: SeriesPattern1[StoredF32] = SeriesPattern1(client, 'stock_to_flow')
|
||||
self.seller_exhaustion: SeriesPattern1[StoredF32] = SeriesPattern1(client, 'seller_exhaustion')
|
||||
self.thermometer: SeriesTree_Indicators_Thermometer = SeriesTree_Indicators_Thermometer(client)
|
||||
self.realized_envelope: SeriesTree_Indicators_RealizedEnvelope = SeriesTree_Indicators_RealizedEnvelope(client)
|
||||
|
||||
class SeriesTree_Investing_Period_CostBasis:
|
||||
"""Series tree node."""
|
||||
|
||||
@@ -924,6 +924,39 @@ export function createMarketSection() {
|
||||
{
|
||||
name: "Indicators",
|
||||
tree: [
|
||||
{
|
||||
name: "Envelope",
|
||||
title: "Realized Envelope",
|
||||
top: priceBands(percentileBands(indicators.realizedEnvelope), {
|
||||
defaultActive: true,
|
||||
}),
|
||||
bottom: [
|
||||
histogram({
|
||||
series: indicators.realizedEnvelope.index,
|
||||
name: "Index",
|
||||
unit: Unit.count,
|
||||
colorFn: (v) =>
|
||||
/** @type {const} */ ([
|
||||
colors.ratioPct._0_5,
|
||||
colors.ratioPct._1,
|
||||
colors.ratioPct._2,
|
||||
colors.ratioPct._5,
|
||||
colors.transparent,
|
||||
colors.ratioPct._95,
|
||||
colors.ratioPct._98,
|
||||
colors.ratioPct._99,
|
||||
colors.ratioPct._99_5,
|
||||
])[v + 4],
|
||||
}),
|
||||
baseline({
|
||||
series: indicators.realizedEnvelope.score,
|
||||
name: "Score",
|
||||
unit: Unit.count,
|
||||
color: [colors.ratioPct._99, colors.ratioPct._1],
|
||||
defaultActive: false,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Valuation",
|
||||
tree: [
|
||||
@@ -1087,39 +1120,6 @@ export function createMarketSection() {
|
||||
color: colors.loss,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "Thermometer",
|
||||
title: "Thermometer",
|
||||
top: priceBands(percentileBands(indicators.thermometer), {
|
||||
defaultActive: true,
|
||||
}),
|
||||
bottom: [
|
||||
histogram({
|
||||
series: indicators.thermometer.zone,
|
||||
name: "Zone",
|
||||
unit: Unit.count,
|
||||
colorFn: (v) =>
|
||||
/** @type {const} */ ([
|
||||
colors.ratioPct._0_5,
|
||||
colors.ratioPct._1,
|
||||
colors.ratioPct._2,
|
||||
colors.ratioPct._5,
|
||||
colors.transparent,
|
||||
colors.ratioPct._95,
|
||||
colors.ratioPct._98,
|
||||
colors.ratioPct._99,
|
||||
colors.ratioPct._99_5,
|
||||
])[v + 4],
|
||||
}),
|
||||
baseline({
|
||||
series: indicators.thermometer.score,
|
||||
name: "Score",
|
||||
unit: Unit.count,
|
||||
color: [colors.ratioPct._99, colors.ratioPct._1],
|
||||
defaultActive: false,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user