diff --git a/Cargo.lock b/Cargo.lock index cafe6b533..1ba07c93a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -596,6 +596,8 @@ dependencies = [ "fjall", "log", "rayon", + "serde", + "serde_json", "vecdb", ] @@ -2506,9 +2508,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lsm-tree" @@ -2578,11 +2580,10 @@ dependencies = [ [[package]] name = "minreq" -version = "2.14.0" +version = "2.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84885312a86831bff4a3cb04a1e54a3f698407e3274c83249313f194d3e0b678" +checksum = "05015102dad0f7d61691ca347e9d9d9006685a64aefb3d79eecf62665de2153d" dependencies = [ - "log", "rustls", "rustls-webpki", "serde", diff --git a/Cargo.toml b/Cargo.toml index e9f1bd1ac..9419b1214 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,8 +43,8 @@ byteview = "=0.6.1" derive_deref = "1.1.1" fjall = "2.11.2" jiff = "0.2.15" -log = "0.4.27" -minreq = { version = "2.14.0", features = ["https", "serde_json"] } +log = "0.4.28" +minreq = { version = "2.14.1", features = ["https", "serde_json"] } parking_lot = "0.12.4" rayon = "1.11.0" serde = "1.0.219" diff --git a/crates/brk_computer/src/chain.rs b/crates/brk_computer/src/chain.rs index 850930efc..9db733e1e 100644 --- a/crates/brk_computer/src/chain.rs +++ b/crates/brk_computer/src/chain.rs @@ -3,9 +3,10 @@ use std::path::Path; use brk_error::Result; use brk_indexer::Indexer; use brk_structs::{ - CheckedSub, Date, DateIndex, DifficultyEpoch, Dollars, FeeRate, HalvingEpoch, Height, - InputIndex, OutputIndex, Sats, StoredBool, StoredF32, StoredF64, StoredU32, StoredU64, - Timestamp, TxIndex, TxVersion, Version, Weight, + CheckedSub, Date, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, FeeRate, HalvingEpoch, + Height, InputIndex, MonthIndex, OutputIndex, QuarterIndex, Sats, SemesterIndex, StoredBool, + StoredF32, StoredF64, StoredU32, StoredU64, Timestamp, TxIndex, TxVersion, Version, WeekIndex, + Weight, YearIndex, }; use vecdb::{ AnyCloneableIterableVec, AnyCollectableVec, AnyIterableVec, Database, EagerVec, Exit, @@ -20,12 +21,30 @@ use crate::grouped::{ use super::{Indexes, indexes, price}; const VERSION: Version = Version::ZERO; -const TARGET_BLOCKS_PER_DAY: f64 = 144.0; +const TARGET_BLOCKS_PER_DAY_F64: f64 = 144.0; +const TARGET_BLOCKS_PER_DAY: u64 = 144; +const TARGET_BLOCKS_PER_WEEK: u64 = 7 * TARGET_BLOCKS_PER_DAY; +const TARGET_BLOCKS_PER_MONTH: u64 = 30 * TARGET_BLOCKS_PER_DAY; +const TARGET_BLOCKS_PER_QUARTER: u64 = 3 * TARGET_BLOCKS_PER_MONTH; +const TARGET_BLOCKS_PER_SEMESTER: u64 = 2 * TARGET_BLOCKS_PER_QUARTER; +const TARGET_BLOCKS_PER_YEAR: u64 = 2 * TARGET_BLOCKS_PER_SEMESTER; +const TARGET_BLOCKS_PER_DECADE: u64 = 10 * TARGET_BLOCKS_PER_YEAR; #[derive(Clone)] pub struct Vecs { db: Database, + pub dateindex_to_block_count_target: LazyVecFrom1, + pub weekindex_to_block_count_target: LazyVecFrom1, + pub monthindex_to_block_count_target: + LazyVecFrom1, + pub quarterindex_to_block_count_target: + LazyVecFrom1, + pub semesterindex_to_block_count_target: + LazyVecFrom1, + pub yearindex_to_block_count_target: LazyVecFrom1, + pub decadeindex_to_block_count_target: + LazyVecFrom1, pub height_to_interval: EagerVec, pub height_to_vbytes: EagerVec, pub difficultyepoch_to_timestamp: EagerVec, @@ -39,7 +58,6 @@ pub struct Vecs { pub indexes_to_difficulty: ComputedVecsFromHeight, pub indexes_to_difficultyepoch: ComputedVecsFromDateIndex, pub indexes_to_halvingepoch: ComputedVecsFromDateIndex, - pub indexes_to_coinbase: ComputedValueVecsFromHeight, pub indexes_to_emptyoutput_count: ComputedVecsFromHeight, pub indexes_to_fee: ComputedValueVecsFromTxindex, @@ -288,7 +306,57 @@ impl Vecs { let txindex_to_fee_rate = EagerVec::forced_import_compressed(&db, "fee_rate", version + VERSION + Version::ZERO)?; + let dateindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + VERSION + Version::ZERO, + indexes.dateindex_to_dateindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DAY)), + ); + let weekindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + VERSION + Version::ZERO, + indexes.weekindex_to_weekindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_WEEK)), + ); + let monthindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + VERSION + Version::ZERO, + indexes.monthindex_to_monthindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_MONTH)), + ); + let quarterindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + VERSION + Version::ZERO, + indexes.quarterindex_to_quarterindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_QUARTER)), + ); + let semesterindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + VERSION + Version::ZERO, + indexes.semesterindex_to_semesterindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_SEMESTER)), + ); + let yearindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + VERSION + Version::ZERO, + indexes.yearindex_to_yearindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_YEAR)), + ); + let decadeindex_to_block_count_target = LazyVecFrom1::init( + "block_count_target", + version + VERSION + Version::ZERO, + indexes.decadeindex_to_decadeindex.boxed_clone(), + |_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DECADE)), + ); + let this = Self { + dateindex_to_block_count_target, + weekindex_to_block_count_target, + monthindex_to_block_count_target, + quarterindex_to_block_count_target, + semesterindex_to_block_count_target, + yearindex_to_block_count_target, + decadeindex_to_block_count_target, height_to_interval: EagerVec::forced_import_compressed( &db, "interval", @@ -1538,7 +1606,7 @@ impl Vecs { i, StoredF64::from( (f64::from(block_count_sum) - / (target_multiplier * TARGET_BLOCKS_PER_DAY)) + / (target_multiplier * TARGET_BLOCKS_PER_DAY_F64)) * f64::from(difficulty_as_hash), ), ) @@ -1686,6 +1754,13 @@ impl Vecs { &self.txindex_to_weight, &self.dateindex_to_fee_dominance, &self.dateindex_to_subsidy_dominance, + &self.dateindex_to_block_count_target, + &self.weekindex_to_block_count_target, + &self.monthindex_to_block_count_target, + &self.quarterindex_to_block_count_target, + &self.semesterindex_to_block_count_target, + &self.yearindex_to_block_count_target, + &self.decadeindex_to_block_count_target, ], self.indexes_to_hash_rate.vecs(), self.indexes_to_hash_rate_1w_sma.vecs(), diff --git a/crates/brk_computer/src/constants.rs b/crates/brk_computer/src/constants.rs index d1b509cc0..9d0ac9323 100644 --- a/crates/brk_computer/src/constants.rs +++ b/crates/brk_computer/src/constants.rs @@ -26,7 +26,6 @@ pub struct Vecs { pub constant_4: ComputedVecsFromHeight, pub constant_50: ComputedVecsFromHeight, pub constant_100: ComputedVecsFromHeight, - pub constant_144: ComputedVecsFromHeight, pub constant_600: ComputedVecsFromHeight, pub constant_minus_1: ComputedVecsFromHeight, pub constant_minus_2: ComputedVecsFromHeight, @@ -95,14 +94,6 @@ impl Vecs { indexes, VecBuilderOptions::default().add_last(), )?, - constant_144: ComputedVecsFromHeight::forced_import( - &db, - "constant_144", - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, constant_600: ComputedVecsFromHeight::forced_import( &db, "constant_600", @@ -184,7 +175,6 @@ impl Vecs { (&mut self.constant_4, 4), (&mut self.constant_50, 50), (&mut self.constant_100, 100), - (&mut self.constant_144, 144), (&mut self.constant_600, 600), ] .into_iter() @@ -245,7 +235,6 @@ impl Vecs { self.constant_4.vecs(), self.constant_50.vecs(), self.constant_100.vecs(), - self.constant_144.vecs(), self.constant_600.vecs(), self.constant_minus_1.vecs(), self.constant_minus_2.vecs(), diff --git a/crates/brk_computer/src/stateful/common.rs b/crates/brk_computer/src/stateful/common.rs index 1140c41a9..5b9132041 100644 --- a/crates/brk_computer/src/stateful/common.rs +++ b/crates/brk_computer/src/stateful/common.rs @@ -77,8 +77,10 @@ pub struct Vecs { pub indexes_to_value_destroyed: Option>, pub indexes_to_unrealized_profit: Option>, pub indexes_to_unrealized_loss: Option>, - pub height_to_unrealized_total_pnl: Option>, - pub indexes_to_unrealized_total_pnl: Option>, + pub height_to_total_unrealized_pnl: Option>, + pub indexes_to_total_unrealized_pnl: Option>, + pub height_to_total_realized_pnl: Option>, + pub indexes_to_total_realized_pnl: Option>, pub indexes_to_min_price_paid: Option>, pub indexes_to_max_price_paid: Option>, pub height_to_supply_half_value: ComputedHeightValueVecs, @@ -110,21 +112,21 @@ pub struct Vecs { Option>, pub indexes_to_net_unrealized_pnl_rel_to_own_market_cap: Option>, - pub height_to_unrealized_profit_rel_to_own_unrealized_total_pnl: + pub height_to_unrealized_profit_rel_to_own_total_unrealized_pnl: Option>, - pub height_to_unrealized_loss_rel_to_own_unrealized_total_pnl: + pub height_to_unrealized_loss_rel_to_own_total_unrealized_pnl: Option>, - pub height_to_neg_unrealized_loss_rel_to_own_unrealized_total_pnl: + pub height_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl: Option>, - pub height_to_net_unrealized_pnl_rel_to_own_unrealized_total_pnl: + pub height_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl: Option>, - pub indexes_to_unrealized_profit_rel_to_own_unrealized_total_pnl: + pub indexes_to_unrealized_profit_rel_to_own_total_unrealized_pnl: Option>, - pub indexes_to_unrealized_loss_rel_to_own_unrealized_total_pnl: + pub indexes_to_unrealized_loss_rel_to_own_total_unrealized_pnl: Option>, - pub indexes_to_neg_unrealized_loss_rel_to_own_unrealized_total_pnl: + pub indexes_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl: Option>, - pub indexes_to_net_unrealized_pnl_rel_to_own_unrealized_total_pnl: + pub indexes_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl: Option>, pub indexes_to_realized_cap_rel_to_own_market_cap: Option>, pub indexes_to_realized_profit_rel_to_realized_cap: Option>, @@ -370,18 +372,18 @@ impl Vecs { ) .unwrap() }), - height_to_unrealized_total_pnl: compute_dollars.then(|| { + height_to_total_unrealized_pnl: compute_dollars.then(|| { EagerVec::forced_import_compressed( db, - &suffix("unrealized_total_pnl"), + &suffix("total_unrealized_pnl"), version + VERSION + Version::ZERO, ) .unwrap() }), - indexes_to_unrealized_total_pnl: compute_dollars.then(|| { + indexes_to_total_unrealized_pnl: compute_dollars.then(|| { ComputedVecsFromDateIndex::forced_import( db, - &suffix("unrealized_total_pnl"), + &suffix("total_unrealized_pnl"), Source::Compute, version + VERSION + Version::ZERO, indexes, @@ -389,6 +391,25 @@ impl Vecs { ) .unwrap() }), + height_to_total_realized_pnl: compute_dollars.then(|| { + EagerVec::forced_import_compressed( + db, + &suffix("total_realized_pnl"), + version + VERSION + Version::ZERO, + ) + .unwrap() + }), + indexes_to_total_realized_pnl: compute_dollars.then(|| { + ComputedVecsFromDateIndex::forced_import( + db, + &suffix("total_realized_pnl"), + Source::Compute, + version + VERSION + Version::ONE, + indexes, + VecBuilderOptions::default().add_sum(), + ) + .unwrap() + }), dateindex_to_unrealized_loss, height_to_realized_cap: compute_dollars.then(|| { EagerVec::forced_import( @@ -990,56 +1011,56 @@ impl Vecs { ) .unwrap() }), - height_to_unrealized_profit_rel_to_own_unrealized_total_pnl: (compute_dollars + height_to_unrealized_profit_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) .then(|| { EagerVec::forced_import( db, - &suffix("unrealized_profit_rel_to_own_unrealized_total_pnl"), + &suffix("unrealized_profit_rel_to_own_total_unrealized_pnl"), version + VERSION + Version::ZERO, format, ) .unwrap() }), - height_to_unrealized_loss_rel_to_own_unrealized_total_pnl: (compute_dollars + height_to_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) .then(|| { EagerVec::forced_import( db, - &suffix("unrealized_loss_rel_to_own_unrealized_total_pnl"), + &suffix("unrealized_loss_rel_to_own_total_unrealized_pnl"), version + VERSION + Version::ZERO, format, ) .unwrap() }), - height_to_neg_unrealized_loss_rel_to_own_unrealized_total_pnl: (compute_dollars + height_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) .then(|| { EagerVec::forced_import( db, - &suffix("neg_unrealized_loss_rel_to_own_unrealized_total_pnl"), + &suffix("neg_unrealized_loss_rel_to_own_total_unrealized_pnl"), version + VERSION + Version::ZERO, format, ) .unwrap() }), - height_to_net_unrealized_pnl_rel_to_own_unrealized_total_pnl: (compute_dollars + height_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) .then(|| { EagerVec::forced_import( db, - &suffix("net_unrealized_pnl_rel_to_own_unrealized_total_pnl"), + &suffix("net_unrealized_pnl_rel_to_own_total_unrealized_pnl"), version + VERSION + Version::ONE, format, ) .unwrap() }), - indexes_to_unrealized_profit_rel_to_own_unrealized_total_pnl: (compute_dollars + indexes_to_unrealized_profit_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) .then(|| { ComputedVecsFromDateIndex::forced_import( db, - &suffix("unrealized_profit_rel_to_own_unrealized_total_pnl"), + &suffix("unrealized_profit_rel_to_own_total_unrealized_pnl"), Source::Compute, version + VERSION + Version::ONE, indexes, @@ -1047,12 +1068,12 @@ impl Vecs { ) .unwrap() }), - indexes_to_unrealized_loss_rel_to_own_unrealized_total_pnl: (compute_dollars + indexes_to_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) .then(|| { ComputedVecsFromDateIndex::forced_import( db, - &suffix("unrealized_loss_rel_to_own_unrealized_total_pnl"), + &suffix("unrealized_loss_rel_to_own_total_unrealized_pnl"), Source::Compute, version + VERSION + Version::ONE, indexes, @@ -1060,12 +1081,12 @@ impl Vecs { ) .unwrap() }), - indexes_to_neg_unrealized_loss_rel_to_own_unrealized_total_pnl: (compute_dollars + indexes_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) .then(|| { ComputedVecsFromDateIndex::forced_import( db, - &suffix("neg_unrealized_loss_rel_to_own_unrealized_total_pnl"), + &suffix("neg_unrealized_loss_rel_to_own_total_unrealized_pnl"), Source::Compute, version + VERSION + Version::ONE, indexes, @@ -1073,12 +1094,12 @@ impl Vecs { ) .unwrap() }), - indexes_to_net_unrealized_pnl_rel_to_own_unrealized_total_pnl: (compute_dollars + indexes_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) .then(|| { ComputedVecsFromDateIndex::forced_import( db, - &suffix("net_unrealized_pnl_rel_to_own_unrealized_total_pnl"), + &suffix("net_unrealized_pnl_rel_to_own_total_unrealized_pnl"), Source::Compute, version + VERSION + Version::ONE, indexes, @@ -2673,7 +2694,7 @@ impl Vecs { exit, Some(self.dateindex_to_unrealized_loss.as_ref().unwrap()), )?; - self.height_to_unrealized_total_pnl + self.height_to_total_unrealized_pnl .as_mut() .unwrap() .compute_add( @@ -2682,7 +2703,7 @@ impl Vecs { self.height_to_unrealized_loss.as_ref().unwrap(), exit, )?; - self.indexes_to_unrealized_total_pnl + self.indexes_to_total_unrealized_pnl .as_mut() .unwrap() .compute_all( @@ -2700,6 +2721,41 @@ impl Vecs { Ok(()) }, )?; + self.height_to_total_realized_pnl + .as_mut() + .unwrap() + .compute_add( + starting_indexes.height, + self.height_to_realized_profit.as_ref().unwrap(), + self.height_to_realized_loss.as_ref().unwrap(), + exit, + )?; + self.indexes_to_total_realized_pnl + .as_mut() + .unwrap() + .compute_all( + indexer, + indexes, + starting_indexes, + exit, + |vec, _, _, starting_indexes, exit| { + vec.compute_add( + starting_indexes.dateindex, + self.indexes_to_realized_profit + .as_ref() + .unwrap() + .dateindex + .unwrap_sum(), + self.indexes_to_realized_loss + .as_ref() + .unwrap() + .dateindex + .unwrap_sum(), + exit, + )?; + Ok(()) + }, + )?; self.indexes_to_min_price_paid .as_mut() @@ -3043,46 +3099,46 @@ impl Vecs { } if self - .height_to_unrealized_profit_rel_to_own_unrealized_total_pnl + .height_to_unrealized_profit_rel_to_own_total_unrealized_pnl .is_some() { - self.height_to_unrealized_profit_rel_to_own_unrealized_total_pnl + self.height_to_unrealized_profit_rel_to_own_total_unrealized_pnl .as_mut() .unwrap() .compute_percentage( starting_indexes.height, self.height_to_unrealized_profit.as_ref().unwrap(), - self.height_to_unrealized_total_pnl.as_ref().unwrap(), + self.height_to_total_unrealized_pnl.as_ref().unwrap(), exit, )?; - self.height_to_unrealized_loss_rel_to_own_unrealized_total_pnl + self.height_to_unrealized_loss_rel_to_own_total_unrealized_pnl .as_mut() .unwrap() .compute_percentage( starting_indexes.height, self.height_to_unrealized_loss.as_ref().unwrap(), - self.height_to_unrealized_total_pnl.as_ref().unwrap(), + self.height_to_total_unrealized_pnl.as_ref().unwrap(), exit, )?; - self.height_to_neg_unrealized_loss_rel_to_own_unrealized_total_pnl + self.height_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl .as_mut() .unwrap() .compute_percentage( starting_indexes.height, self.height_to_neg_unrealized_loss.as_ref().unwrap(), - self.height_to_unrealized_total_pnl.as_ref().unwrap(), + self.height_to_total_unrealized_pnl.as_ref().unwrap(), exit, )?; - self.height_to_net_unrealized_pnl_rel_to_own_unrealized_total_pnl + self.height_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl .as_mut() .unwrap() .compute_percentage( starting_indexes.height, self.height_to_net_unrealized_pnl.as_ref().unwrap(), - self.height_to_unrealized_total_pnl.as_ref().unwrap(), + self.height_to_total_unrealized_pnl.as_ref().unwrap(), exit, )?; - self.indexes_to_unrealized_profit_rel_to_own_unrealized_total_pnl + self.indexes_to_unrealized_profit_rel_to_own_total_unrealized_pnl .as_mut() .unwrap() .compute_all( @@ -3094,7 +3150,7 @@ impl Vecs { vec.compute_percentage( starting_indexes.dateindex, self.dateindex_to_unrealized_profit.as_ref().unwrap(), - self.indexes_to_unrealized_total_pnl + self.indexes_to_total_unrealized_pnl .as_ref() .unwrap() .dateindex @@ -3105,7 +3161,7 @@ impl Vecs { Ok(()) }, )?; - self.indexes_to_unrealized_loss_rel_to_own_unrealized_total_pnl + self.indexes_to_unrealized_loss_rel_to_own_total_unrealized_pnl .as_mut() .unwrap() .compute_all( @@ -3117,7 +3173,7 @@ impl Vecs { vec.compute_percentage( starting_indexes.dateindex, self.dateindex_to_unrealized_loss.as_ref().unwrap(), - self.indexes_to_unrealized_total_pnl + self.indexes_to_total_unrealized_pnl .as_ref() .unwrap() .dateindex @@ -3128,7 +3184,7 @@ impl Vecs { Ok(()) }, )?; - self.indexes_to_neg_unrealized_loss_rel_to_own_unrealized_total_pnl + self.indexes_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl .as_mut() .unwrap() .compute_all( @@ -3145,7 +3201,7 @@ impl Vecs { .dateindex .as_ref() .unwrap(), - self.indexes_to_unrealized_total_pnl + self.indexes_to_total_unrealized_pnl .as_ref() .unwrap() .dateindex @@ -3156,7 +3212,7 @@ impl Vecs { Ok(()) }, )?; - self.indexes_to_net_unrealized_pnl_rel_to_own_unrealized_total_pnl + self.indexes_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl .as_mut() .unwrap() .compute_all( @@ -3173,7 +3229,7 @@ impl Vecs { .dateindex .as_ref() .unwrap(), - self.indexes_to_unrealized_total_pnl + self.indexes_to_total_unrealized_pnl .as_ref() .unwrap() .dateindex @@ -3806,10 +3862,16 @@ impl Vecs { self.indexes_to_unrealized_loss .as_ref() .map_or(vec![], |v| v.vecs()), - self.height_to_unrealized_total_pnl + self.height_to_total_unrealized_pnl .as_ref() .map_or(vec![], |v| vec![v]), - self.indexes_to_unrealized_total_pnl + self.indexes_to_total_unrealized_pnl + .as_ref() + .map_or(vec![], |v| v.vecs()), + self.height_to_total_realized_pnl + .as_ref() + .map_or(vec![], |v| vec![v]), + self.indexes_to_total_realized_pnl .as_ref() .map_or(vec![], |v| v.vecs()), self.indexes_to_min_price_paid @@ -3843,28 +3905,28 @@ impl Vecs { self.indexes_to_net_unrealized_pnl_rel_to_own_market_cap .as_ref() .map_or(vec![], |v| v.vecs()), - self.height_to_unrealized_profit_rel_to_own_unrealized_total_pnl + self.height_to_unrealized_profit_rel_to_own_total_unrealized_pnl .as_ref() .map_or(vec![], |v| vec![v]), - self.height_to_unrealized_loss_rel_to_own_unrealized_total_pnl + self.height_to_unrealized_loss_rel_to_own_total_unrealized_pnl .as_ref() .map_or(vec![], |v| vec![v]), - self.height_to_neg_unrealized_loss_rel_to_own_unrealized_total_pnl + self.height_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl .as_ref() .map_or(vec![], |v| vec![v]), - self.height_to_net_unrealized_pnl_rel_to_own_unrealized_total_pnl + self.height_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl .as_ref() .map_or(vec![], |v| vec![v]), - self.indexes_to_unrealized_profit_rel_to_own_unrealized_total_pnl + self.indexes_to_unrealized_profit_rel_to_own_total_unrealized_pnl .as_ref() .map_or(vec![], |v| v.vecs()), - self.indexes_to_unrealized_loss_rel_to_own_unrealized_total_pnl + self.indexes_to_unrealized_loss_rel_to_own_total_unrealized_pnl .as_ref() .map_or(vec![], |v| v.vecs()), - self.indexes_to_neg_unrealized_loss_rel_to_own_unrealized_total_pnl + self.indexes_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl .as_ref() .map_or(vec![], |v| v.vecs()), - self.indexes_to_net_unrealized_pnl_rel_to_own_unrealized_total_pnl + self.indexes_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl .as_ref() .map_or(vec![], |v| v.vecs()), self.height_to_neg_unrealized_loss diff --git a/crates/brk_store/src/any.rs b/crates/brk_store/src/any.rs index 0bf2f967e..d116af82e 100644 --- a/crates/brk_store/src/any.rs +++ b/crates/brk_store/src/any.rs @@ -3,18 +3,11 @@ use brk_structs::{Height, Version}; pub trait AnyStore { fn commit(&mut self, height: Height) -> Result<()>; - fn persist(&self) -> Result<()>; - fn reset(&mut self) -> Result<()>; - fn name(&self) -> &'static str; - fn height(&self) -> Option; - fn has(&self, height: Height) -> bool; - fn needs(&self, height: Height) -> bool; - fn version(&self) -> Version; } diff --git a/crates/brk_store/src/lib.rs b/crates/brk_store/src/lib.rs index 34e374cd7..f9bc24236 100644 --- a/crates/brk_store/src/lib.rs +++ b/crates/brk_store/src/lib.rs @@ -126,12 +126,12 @@ where // .map(|(k, v)| (K::from(ByteView::from(k)), V::from(ByteView::from(v))))) // } - // pub fn tx_iter(&self) -> impl Iterator { - // self.rtx - // .iter(&self.partition.load()) - // .map(|res| res.unwrap()) - // .map(|(k, v)| (K::from(ByteView::from(k)), V::from(ByteView::from(v)))) - // } + pub fn iter(&self) -> impl Iterator { + self.rtx + .iter(self.partition.as_ref().unwrap()) + .map(|res| res.unwrap()) + .map(|(k, v)| (K::from(ByteView::from(k)), V::from(ByteView::from(v)))) + } pub fn insert_if_needed(&mut self, key: K, value: V, height: Height) { if self.needs(height) { diff --git a/websites/bitview/index.html b/websites/bitview/index.html index 79f0ecefd..4bbdb0721 100644 --- a/websites/bitview/index.html +++ b/websites/bitview/index.html @@ -572,6 +572,7 @@ &:has(input:checked) { color: var(--color); + font-style: normal; } [data-screenshot="true"] &:has(input:not(:checked)) { @@ -950,6 +951,7 @@ display: flex; align-items: center; gap: 1rem; + /*font-style: italic;*/ > legend, > div { @@ -1051,6 +1053,7 @@ &:has(input:not(:checked)) { color: var(--off-color); + /*font-style: italic;*/ > span.main > span.name { text-decoration-thickness: 1.5px; diff --git a/websites/bitview/scripts/main.js b/websites/bitview/scripts/main.js index e2d64baa6..9652ed813 100644 --- a/websites/bitview/scripts/main.js +++ b/websites/bitview/scripts/main.js @@ -934,7 +934,7 @@ function createUtils() { } if ( (!unit || thoroughUnitCheck) && - id.endsWith("rel_to_own_unrealized_total_pnl") + id.endsWith("rel_to_own_total_unrealized_pnl") ) { setUnit("%cp+l"); } diff --git a/websites/bitview/scripts/options.js b/websites/bitview/scripts/options.js index adea4a10f..83b23f6e9 100644 --- a/websites/bitview/scripts/options.js +++ b/websites/bitview/scripts/options.js @@ -213,6 +213,19 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { { year: 2025, color: colors.pink, defaultActive: true }, ]); + const cohortAll = /** @type {const} */ ({ + key: "", + name: "", + title: "", + color: colors.orange, + }); + const cohortAllForComparaison = /** @type {const} */ ({ + key: "", + name: "all", + title: "", + color: colors.default, + }); + const terms = /** @type {const} */ ([ { key: "sth", @@ -1722,14 +1735,6 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), ] : []), - createBaseSeries({ - key: `${key}supply_half`, - name: "Halved", - color: colors.gray, - options: { - lineStyle: 4, - }, - }), createBaseSeries({ key: `${key}supply_in_profit`, name: "In Profit", @@ -1762,22 +1767,30 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), createBaseSeries({ key: `${key}supply_breakeven`, - name: useGroupName ? name : "Even", + name: useGroupName ? name : "breakeven", color: colors.yellow, }), createBaseSeries({ key: `${key}supply_breakeven_in_btc`, - name: useGroupName ? name : "Even", + name: useGroupName ? name : "breakeven", color: colors.yellow, }), createBaseSeries({ key: `${key}supply_breakeven_in_usd`, - name: useGroupName ? name : "Even", + name: useGroupName ? name : "breakeven", color: colors.yellow, }), + createBaseSeries({ + key: `${key}supply_half`, + name: "half", + color: colors.gray, + options: { + lineStyle: 4, + }, + }), createBaseSeries({ key: `${key}supply_half_in_btc`, - name: useGroupName ? name : "Halved", + name: useGroupName ? name : "half", color: "list" in args ? color : colors.gray, options: { lineStyle: 4, @@ -1785,7 +1798,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), createBaseSeries({ key: `${key}supply_half_in_usd`, - name: useGroupName ? name : "Halved", + name: useGroupName ? name : "half", color: "list" in args ? color : colors.gray, options: { lineStyle: 4, @@ -1805,7 +1818,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), createBaseSeries({ key: `${key}supply_breakeven_rel_to_circulating_supply`, - name: "Even", + name: "breakeven", color: colors.yellow, }), ] @@ -1822,7 +1835,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), createBaseSeries({ key: `${key}supply_breakeven_rel_to_own_supply`, - name: "Even", + name: "breakeven", color: colors.yellow, }), createPriceLine({ @@ -1862,15 +1875,18 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { name, color, }), - ...(key - ? [ - createBaseSeries({ - key: `${key}supply_rel_to_circulating_supply`, - name, - color, - }), - ] - : []), + key + ? createBaseSeries({ + key: `${key}supply_rel_to_circulating_supply`, + name, + color, + }) + : createBaseSeries({ + unit: "%all", + key: "constant_100", + name, + color, + }), ]); }), }, @@ -1904,11 +1920,6 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), ] : []), - createBaseSeries({ - key: `${key}supply_in_profit_rel_to_own_supply`, - name, - color, - }), ]); }), }, @@ -1942,17 +1953,12 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), ] : []), - createBaseSeries({ - key: `${key}supply_in_loss_rel_to_own_supply`, - name, - color, - }), ]); }), }, { - name: "even", - title: `Even Supply ${title}`, + name: "breakeven", + title: `Supply At Breaken ${title}`, bottom: list.flatMap(({ color, name, key: _key }) => { const key = fixKey(_key); return /** @type {const} */ ([ @@ -2006,11 +2012,11 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }, ...(list.filter( ({ key }) => `${fixKey(key)}addr_count` in vecIdToIndexes, - ).length + ).length > ("list" in args ? 1 : 0) ? !("list" in args) || list.filter( ({ key }) => `${fixKey(key)}empty_addr_count` in vecIdToIndexes, - ).length == 0 + ).length <= 1 ? [ { name: "address count", @@ -2103,7 +2109,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { { name: "Price", title: `Realized Price ${title}`, - top: args.list.map(({ color, name, key }) => + top: list.map(({ color, name, key }) => createBaseSeries({ key: `${fixKey(key)}realized_price`, name, @@ -2111,6 +2117,23 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), ), }, + { + name: "Ratio", + title: `Realized Price Ratio ${title}`, + bottom: [ + ...list.map(({ color, name, key }) => + createBaseSeries({ + key: `${fixKey(key)}realized_price_ratio`, + name, + color, + }), + ), + createPriceLine({ + unit: "Ratio", + number: 1, + }), + ], + }, ] : createPriceWithRatioOptions({ title: `Realized Price ${title}`, @@ -2144,23 +2167,6 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), ] : []), - ...(`${key}realized_cap_rel_to_own_market_cap` in - vecIdToIndexes - ? [ - /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ - type: "Baseline", - key: `${key}realized_cap_rel_to_own_market_cap`, - title: "ratio", - options: { baseValue: { price: 100 } }, - colors: [colors.red, colors.green], - }), - createPriceLine({ - unit: "%cmcap", - defaultActive: true, - number: 100, - }), - ] - : []), ]); }), }, @@ -2175,29 +2181,35 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { name: "Profit", color: colors.green, }), - createBaseSeries({ - key: `${fixKey(args.key)}realized_profit_cumulative`, - name: "Cumulative Profit", - color: colors.green, - defaultActive: false, - }), createBaseSeries({ key: `${fixKey(args.key)}realized_loss`, name: "Loss", color: colors.red, defaultActive: false, }), + createBaseSeries({ + key: `${fixKey(args.key)}total_realized_pnl`, + name: "Total", + color: colors.default, + defaultActive: false, + }), + createBaseSeries({ + key: `${fixKey(args.key)}neg_realized_loss`, + name: "Negative Loss", + color: colors.red, + }), + createBaseSeries({ + key: `${fixKey(args.key)}realized_profit_cumulative`, + name: "Cumulative Profit", + color: colors.green, + defaultActive: false, + }), createBaseSeries({ key: `${fixKey(args.key)}realized_loss_cumulative`, name: "Cumulative Loss", color: colors.red, defaultActive: false, }), - createBaseSeries({ - key: `${fixKey(args.key)}neg_realized_loss`, - name: "Negative Loss", - color: colors.red, - }), createBaseSeries({ key: `${fixKey(args.key)}neg_realized_loss_cumulative`, name: "Cumulative Negative Loss", @@ -2433,6 +2445,22 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), ], }, + { + name: "Total pnl", + title: `Total Realized Profit And Loss Loss ${title}`, + bottom: [ + ...list.flatMap(({ color, name, key: _key }) => { + const key = fixKey(_key); + return /** @type {const} */ ([ + createBaseSeries({ + key: `${key}total_realized_pnl`, + name, + color, + }), + ]); + }), + ], + }, { name: "Net pnl", title: `Net Realized Profit And Loss ${title}`, @@ -2613,7 +2641,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { ]), { - name: "Sell Side Risk Ratio", + name: "Sell Side Risk", title: `Sell Side Risk Ratio ${title}`, bottom: !("list" in args) ? list.flatMap(({ key }) => [ @@ -2655,8 +2683,8 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { title: `Unrealized Profit And Loss ${title}`, bottom: [ createBaseSeries({ - key: `${fixKey(args.key)}unrealized_total_pnl`, - name: "profit+loss", + key: `${fixKey(args.key)}total_unrealized_pnl`, + name: "total", color: colors.default, }), createBaseSeries({ @@ -2719,22 +2747,22 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), ] : []), - ...(`${fixKey(args.key)}unrealized_profit_rel_to_own_unrealized_total_pnl` in + ...(`${fixKey(args.key)}unrealized_profit_rel_to_own_total_unrealized_pnl` in vecIdToIndexes ? [ createBaseSeries({ - key: `${fixKey(args.key)}unrealized_profit_rel_to_own_unrealized_total_pnl`, + key: `${fixKey(args.key)}unrealized_profit_rel_to_own_total_unrealized_pnl`, name: "Profit", color: colors.green, }), createBaseSeries({ - key: `${fixKey(args.key)}unrealized_loss_rel_to_own_unrealized_total_pnl`, + key: `${fixKey(args.key)}unrealized_loss_rel_to_own_total_unrealized_pnl`, name: "Loss", color: colors.red, defaultActive: false, }), createBaseSeries({ - key: `${fixKey(args.key)}neg_unrealized_loss_rel_to_own_unrealized_total_pnl`, + key: `${fixKey(args.key)}neg_unrealized_loss_rel_to_own_total_unrealized_pnl`, name: "Negative Loss", color: colors.red, }), @@ -2767,8 +2795,8 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { return /** @type {const} */ ([ createBaseSeries({ key: `${key}unrealized_profit`, - name: useGroupName ? name : "Profit", - color: useGroupName ? color : colors.green, + name, + color, }), ]); }), @@ -2781,8 +2809,22 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { return /** @type {const} */ ([ createBaseSeries({ key: `${key}unrealized_loss`, - name: useGroupName ? name : "Loss", - color: useGroupName ? color : colors.red, + name, + color, + }), + ]); + }), + }, + { + name: "total pnl", + title: `Unrealized Total Profit And Loss ${title}`, + bottom: list.flatMap(({ color, name, key: _key }) => { + const key = fixKey(_key); + return /** @type {const} */ ([ + createBaseSeries({ + key: `${key}total_unrealized_pnl`, + name, + color, }), ]); }), @@ -2821,14 +2863,14 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { }), ] : []), - ...(`${fixKey(key)}net_unrealized_pnl_rel_to_own_unrealized_total_pnl` in + ...(`${fixKey(key)}net_unrealized_pnl_rel_to_own_total_unrealized_pnl` in vecIdToIndexes ? [ /** @satisfies {FetchedBaselineSeriesBlueprint} */ ({ type: "Baseline", key: `${fixKey( key, - )}net_unrealized_pnl_rel_to_own_unrealized_total_pnl`, + )}net_unrealized_pnl_rel_to_own_total_unrealized_pnl`, title: useGroupName ? name : "Net", color: useGroupName ? color : undefined, }), @@ -3293,10 +3335,13 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { ...createSumCumulativeSeries({ concat: "block_count", }), - createPriceLine({ - unit: "Count", + createBaseSeries({ + key: "block_count_target", name: "Target", - number: 144, + color: colors.gray, + options: { + lineStyle: 4, + }, }), ], }, @@ -3722,19 +3767,14 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { { name: "Cohorts", tree: [ - createCohortGroupFolder({ - key: "", - name: "", - title: "", - color: colors.orange, - }), + createCohortGroupFolder(cohortAll), { name: "terms", tree: [ createCohortGroupFolder({ name: "Compare", title: "UTXOs Term", - list: terms, + list: [...terms, cohortAllForComparaison], }), ...terms.map(createCohortGroupFolder), ], @@ -3745,7 +3785,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "Epoch", - list: epoch, + list: [...epoch, cohortAllForComparaison], }), ...epoch.map(createCohortGroupFolder), ], @@ -3756,7 +3796,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "Type", - list: type, + list: [...type, cohortAllForComparaison], }), ...type.map(createCohortGroupFolder), ], @@ -3767,7 +3807,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "UTXOs Up To Age", - list: upToDate, + list: [...upToDate, cohortAllForComparaison], }), ...upToDate.map(createCohortGroupFolder), ], @@ -3778,7 +3818,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "UTXOs from age", - list: fromDate, + list: [...fromDate, cohortAllForComparaison], }), ...fromDate.map(createCohortGroupFolder), ], @@ -3789,7 +3829,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "UTXOs Age Range", - list: dateRange, + list: [...dateRange, cohortAllForComparaison], }), ...dateRange.map(createCohortGroupFolder), ], @@ -3800,7 +3840,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "UTXOs under amount", - list: utxosUnderAmount, + list: [...utxosUnderAmount, cohortAllForComparaison], }), ...utxosUnderAmount.map(createCohortGroupFolder), ], @@ -3811,7 +3851,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "UTXOs Above Amount", - list: utxosAboveAmount, + list: [...utxosAboveAmount, cohortAllForComparaison], }), ...utxosAboveAmount.map(createCohortGroupFolder), ], @@ -3822,7 +3862,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "UTXOs between amounts", - list: utxosAmountRanges, + list: [...utxosAmountRanges, cohortAllForComparaison], }), ...utxosAmountRanges.map(createCohortGroupFolder), ], @@ -3833,7 +3873,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "Addresses under Amount", - list: addressesUnderAmount, + list: [...addressesUnderAmount, cohortAllForComparaison], }), ...addressesUnderAmount.map(createCohortGroupFolder), ], @@ -3844,7 +3884,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "Addresses above amount", - list: addressesAboveAmount, + list: [...addressesAboveAmount, cohortAllForComparaison], }), ...addressesAboveAmount.map(createCohortGroupFolder), ], @@ -3855,7 +3895,7 @@ function createPartialOptions({ env, colors, vecIdToIndexes }) { createCohortGroupFolder({ name: "Compare", title: "Addresses between amounts", - list: addressesAmountRanges, + list: [...addressesAmountRanges, cohortAllForComparaison], }), ...addressesAmountRanges.map(createCohortGroupFolder), ], @@ -4160,10 +4200,10 @@ export function initOptions({ .split("/") .filter((v) => v); const urlPath = urlPath_.length ? urlPath_ : undefined; - const savedPath = utils.storage - .read(LS_SELECTED_KEY) - ?.split("/") - .filter((v) => v); + const savedPath = /** @type {string[]} */ ( + JSON.parse(utils.storage.read(LS_SELECTED_KEY) || "[]") || [] + ).filter((v) => v); + console.log(savedPath); /** @type {Signal