computer + kibo: part 14 - fixes

This commit is contained in:
nym21
2025-04-19 11:45:26 +02:00
parent b1dcad86b4
commit d78c39fd8c
13 changed files with 121 additions and 88 deletions
@@ -209,8 +209,6 @@ where
) -> Result<()>
where
I2: StoredIndex + StoredType,
T: Ord + From<f64>,
f64: From<T>,
{
let index = self.starting_index(max_from);
@@ -295,20 +293,14 @@ where
if needs_average_sum_or_total {
let len = values.len();
let sum = values.into_iter().fold(T::from(0), |a, b| a + b);
if let Some(average) = self.average.as_mut() {
let len = len as f64;
let total = values
.iter()
.map(|v| f64::from(v.clone()))
.fold(0.0, |a, b| a + b);
let avg = T::from(total / len);
let avg = sum.clone() / len;
average.forced_push_at(i, avg, exit)?;
}
if needs_sum_or_total {
let sum = values.into_iter().fold(T::from(0), |a, b| a + b);
if let Some(sum_vec) = self.sum.as_mut() {
sum_vec.forced_push_at(i, sum.clone(), exit)?;
}
@@ -345,8 +337,6 @@ where
) -> Result<()>
where
I2: StoredIndex + StoredType,
T: Ord + From<f64>,
f64: From<T>,
{
if self._90p.is_some()
|| self._75p.is_some()
@@ -415,14 +405,12 @@ where
.as_ref()
.unwrap()
.collect_inclusive_range(first_index, last_index)?;
let len = values.len() as f64;
let total = values
.into_iter()
.map(|v| f64::from(v))
.fold(0.0, |a, b| a + b);
let len = values.len();
let total = values.into_iter().fold(T::from(0), |a, b| a + b);
// TODO: Multiply by count then divide by total
// Right now it's not 100% accurate as there could be more or less elements in the lower timeframe (28 days vs 31 days in a month for example)
let avg = T::from(total / len);
let avg = total / len;
average.forced_push_at(i, avg, exit)?;
}
@@ -432,6 +420,7 @@ where
.as_ref()
.unwrap()
.collect_inclusive_range(first_index, last_index)?;
let sum = values.into_iter().fold(T::from(0), |a, b| a + b);
if let Some(sum_vec) = self.sum.as_mut() {
@@ -27,8 +27,7 @@ const VERSION: Version = Version::ZERO;
impl<T> ComputedVecsFromDateindex<T>
where
T: ComputedType + Ord + From<f64>,
f64: From<T>,
T: ComputedType,
{
pub fn forced_import(
path: &Path,
@@ -4,10 +4,10 @@ use brk_vec::StoredType;
pub trait ComputedType
where
Self: StoredType + From<usize> + Div<usize, Output = Self> + Add<Output = Self>,
Self: StoredType + From<usize> + Div<usize, Output = Self> + Add<Output = Self> + Ord,
{
}
impl<T> ComputedType for T where
T: StoredType + From<usize> + Div<usize, Output = Self> + Add<Output = Self>
T: StoredType + From<usize> + Div<usize, Output = Self> + Add<Output = Self> + Ord
{
}
@@ -65,6 +65,9 @@ pub struct Vecs {
pub decadeindex_to_ohlc_in_sats: ComputedVec<Decadeindex, OHLCSats>,
}
const VERSION: Version = Version::ZERO;
const VERSION_IN_SATS: Version = Version::ONE;
impl Vecs {
pub fn forced_import(path: &Path, compressed: Compressed) -> color_eyre::Result<Self> {
fs::create_dir_all(path)?;
@@ -87,7 +90,7 @@ impl Vecs {
)?,
dateindex_to_ohlc_in_sats: ComputedVec::forced_import(
&path.join("dateindex_to_ohlc_in_sats"),
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
)?,
dateindex_to_close_in_cents: ComputedVec::forced_import(
@@ -122,7 +125,7 @@ impl Vecs {
)?,
height_to_ohlc_in_sats: ComputedVec::forced_import(
&path.join("height_to_ohlc_in_sats"),
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
)?,
height_to_close_in_cents: ComputedVec::forced_import(
@@ -176,28 +179,28 @@ impl Vecs {
timeindexes_to_open_in_sats: ComputedVecsFromDateindex::forced_import(
path,
"open_in_sats",
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_first(),
)?,
timeindexes_to_high_in_sats: ComputedVecsFromDateindex::forced_import(
path,
"high_in_sats",
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_max(),
)?,
timeindexes_to_low_in_sats: ComputedVecsFromDateindex::forced_import(
path,
"low_in_sats",
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_min(),
)?,
timeindexes_to_close_in_sats: ComputedVecsFromDateindex::forced_import(
path,
"close_in_sats",
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_last(),
)?,
@@ -232,28 +235,28 @@ impl Vecs {
chainindexes_to_open_in_sats: ComputedVecsFromHeightStrict::forced_import(
path,
"open_in_sats",
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_first(),
)?,
chainindexes_to_high_in_sats: ComputedVecsFromHeightStrict::forced_import(
path,
"high_in_sats",
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_max(),
)?,
chainindexes_to_low_in_sats: ComputedVecsFromHeightStrict::forced_import(
path,
"low_in_sats",
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_min(),
)?,
chainindexes_to_close_in_sats: ComputedVecsFromHeightStrict::forced_import(
path,
"close_in_sats",
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_last(),
)?,
@@ -264,7 +267,7 @@ impl Vecs {
)?,
weekindex_to_ohlc_in_sats: ComputedVec::forced_import(
&path.join("weekindex_to_ohlc_in_sats"),
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
)?,
difficultyepoch_to_ohlc: ComputedVec::forced_import(
@@ -274,7 +277,7 @@ impl Vecs {
)?,
difficultyepoch_to_ohlc_in_sats: ComputedVec::forced_import(
&path.join("difficultyepoch_to_ohlc_in_sats"),
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
)?,
monthindex_to_ohlc: ComputedVec::forced_import(
@@ -284,7 +287,7 @@ impl Vecs {
)?,
monthindex_to_ohlc_in_sats: ComputedVec::forced_import(
&path.join("monthindex_to_ohlc_in_sats"),
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
)?,
quarterindex_to_ohlc: ComputedVec::forced_import(
@@ -294,7 +297,7 @@ impl Vecs {
)?,
quarterindex_to_ohlc_in_sats: ComputedVec::forced_import(
&path.join("quarterindex_to_ohlc_in_sats"),
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
)?,
yearindex_to_ohlc: ComputedVec::forced_import(
@@ -304,7 +307,7 @@ impl Vecs {
)?,
yearindex_to_ohlc_in_sats: ComputedVec::forced_import(
&path.join("yearindex_to_ohlc_in_sats"),
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
)?,
// halvingepoch_to_ohlc: StorableVec::forced_import(&path.join("halvingepoch_to_ohlc"), Version::ZERO, compressed)?,
@@ -315,7 +318,7 @@ impl Vecs {
)?,
decadeindex_to_ohlc_in_sats: ComputedVec::forced_import(
&path.join("decadeindex_to_ohlc_in_sats"),
Version::ZERO,
VERSION + VERSION_IN_SATS + Version::ZERO,
compressed,
)?,
})
+4 -4
View File
@@ -23,27 +23,27 @@ pub struct Bitcoin(f64);
impl Add for Bitcoin {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
Self::from(Sats::from(self) + Sats::from(rhs))
}
}
impl Mul for Bitcoin {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0 * rhs.0)
Self::from(Sats::from(self) * Sats::from(rhs))
}
}
impl Div<usize> for Bitcoin {
type Output = Self;
fn div(self, rhs: usize) -> Self::Output {
Self(self.0 / rhs as f64)
Self::from(Sats::from(self) / rhs)
}
}
impl From<Sats> for Bitcoin {
fn from(value: Sats) -> Self {
Self(u64::from(value) as f64 / (u64::from(Sats::ONE_BTC) as f64))
Self(f64::from(value) / (f64::from(Sats::ONE_BTC)))
}
}
+16
View File
@@ -1,3 +1,5 @@
use std::ops::{Add, Div};
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -43,3 +45,17 @@ impl From<Cents> for u64 {
value.0
}
}
impl Add for Cents {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl Div<usize> for Cents {
type Output = Self;
fn div(self, rhs: usize) -> Self::Output {
Self(self.0 / rhs as u64)
}
}
+2 -2
View File
@@ -49,14 +49,14 @@ impl From<usize> for Dollars {
impl Add for Dollars {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
Self::from(Cents::from(self) + Cents::from(rhs))
}
}
impl Div<usize> for Dollars {
type Output = Self;
fn div(self, rhs: usize) -> Self::Output {
Self(self.0 / rhs as f64)
Self::from(Cents::from(self) / rhs)
}
}
+12 -6
View File
@@ -9,7 +9,7 @@ use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::CheckedSub;
use super::{Bitcoin, Dollars, Height};
use super::{Bitcoin, Cents, Dollars, Height};
#[derive(
Debug,
@@ -30,6 +30,7 @@ pub struct Sats(u64);
impl Sats {
pub const ZERO: Self = Self(0);
pub const MAX: Self = Self(u64::MAX);
pub const ONE_BTC: Self = Self(100_000_000);
pub fn is_zero(&self) -> bool {
@@ -39,8 +40,8 @@ impl Sats {
impl Add for Sats {
type Output = Self;
fn add(self, rhs: Sats) -> Self::Output {
Sats::from(self.0 + rhs.0)
fn add(self, rhs: Self) -> Self::Output {
Self::from(self.0 + rhs.0)
}
}
@@ -93,7 +94,12 @@ impl Sum for Sats {
impl Div<Dollars> for Sats {
type Output = Self;
fn div(self, rhs: Dollars) -> Self::Output {
Self((self.0 as f64 / f64::from(rhs)) as u64)
let raw_cents = u64::from(Cents::from(rhs));
if raw_cents != 0 {
Self(self.0 * 100 / raw_cents)
} else {
Self::MAX
}
}
}
@@ -118,7 +124,7 @@ impl From<usize> for Sats {
impl From<f64> for Sats {
fn from(value: f64) -> Self {
Self(value as u64)
Self(value.round() as u64)
}
}
@@ -141,7 +147,7 @@ impl From<Sats> for Amount {
impl From<Bitcoin> for Sats {
fn from(value: Bitcoin) -> Self {
Self((f64::from(value) * (u64::from(Sats::ONE_BTC) as f64)).round() as u64)
Self((f64::from(value) * (Sats::ONE_BTC.0 as f64)).round() as u64)
}
}
+7
View File
@@ -64,3 +64,10 @@ impl Div<usize> for Weight {
Self::from(self.0 as usize / rhs)
}
}
impl Div<Weight> for Weight {
type Output = Self;
fn div(self, rhs: Self) -> Self::Output {
Self(self.0 / rhs.0)
}
}
@@ -366,7 +366,7 @@ export default import("./v5.0.5-treeshaked/script.js").then((lc) => {
this.addPriceScaleSelectorIfNeeded({
paneIndex,
seriesType: "Candlestick",
id,
id: `${id}-${paneIndex}`,
unit,
});
@@ -449,7 +449,7 @@ export default import("./v5.0.5-treeshaked/script.js").then((lc) => {
this.addPriceScaleSelectorIfNeeded({
paneIndex,
seriesType: "Line",
id,
id: `${id}-${paneIndex}`,
unit,
});
@@ -532,7 +532,7 @@ export default import("./v5.0.5-treeshaked/script.js").then((lc) => {
this.addPriceScaleSelectorIfNeeded({
paneIndex,
seriesType: "Baseline",
id,
id: `${id}-${paneIndex}`,
unit,
});
+3 -1
View File
@@ -57,12 +57,13 @@ export function init({
/** @satisfies {Unit} */ ("Sats"),
]),
signals,
sorted: true,
});
signals.createEffect(topUnit, (topUnit) => {
const { field: seriesTypeField, selected: topSeriesType } =
utils.dom.createHorizontalChoiceField({
defaultValue: "Candles",
defaultValue: "Line",
keyPrefix: "charts",
key: "seriestype-0",
choices: /** @type {const} */ (["Candles", "Line"]),
@@ -80,6 +81,7 @@ export function init({
key: "unit-1",
choices: bottomUnits,
signals,
sorted: true,
});
signals.createEffect(bottomUnit, (bottomUnit) => {
+10 -1
View File
@@ -330,17 +330,23 @@ function createUtils() {
* @param {T} args.choices
* @param {string} [args.keyPrefix]
* @param {string} args.key
* @param {boolean} [args.sorted]
* @param {{createEffect: CreateEffect, createSignal: Signals["createSignal"]}} args.signals
*/
createHorizontalChoiceField({
title,
id,
choices,
choices: unsortedChoices,
defaultValue,
keyPrefix,
key,
signals,
sorted,
}) {
const choices = sorted
? /** @type {T} */ (/** @type {any} */ (unsortedChoices.toSorted()))
: unsortedChoices;
/** @type {Signal<T[number]>} */
const selected = signals.createSignal(defaultValue, {
save: {
@@ -349,6 +355,9 @@ function createUtils() {
key,
},
});
if (!choices.includes(selected())) {
selected.set(() => defaultValue);
}
const field = window.document.createElement("div");
field.classList.add("field");
+35 -33
View File
@@ -30,8 +30,8 @@
* "Transactions" |
* "USD" |
* "Version" |
* "Virtual Bytes" |
* "Weight Units"
* "vB" |
* "WU"
* } Unit
*
* @typedef {Object} BaseSeriesBlueprint
@@ -224,6 +224,18 @@ function createPartialOptions(colors) {
*/
function createMinMaxPercentilesSeries({ concat }) {
return /** @satisfies {AnyFetchedSeriesBlueprint[]} */ ([
{
key: `${concat}-max`,
title: "Max",
color: colors.pink,
defaultActive: false,
},
{
key: `${concat}-min`,
title: "Min",
color: colors.green,
defaultActive: false,
},
{
key: `${concat}-median`,
title: "Median",
@@ -254,21 +266,20 @@ function createPartialOptions(colors) {
color: colors.lime,
defaultActive: false,
},
{
key: `${concat}-max`,
title: "Max",
color: colors.pink,
defaultActive: false,
},
{
key: `${concat}-min`,
title: "Min",
color: colors.green,
defaultActive: false,
},
]);
}
/**
* @param {VecIdAverageBase & VecIdSumBase & TotalVecIdBase & VecIdMinBase & VecIdMaxBase & VecId90pBase & VecId75pBase & VecIdMedianBase & VecId25pBase & VecId10pBase} key
*/
function createAverageSumTotalMinMaxPercentilesSeries(key) {
return [
createAverageSeries({ concat: key }),
...createSumTotalSeries({ concat: key }),
...createMinMaxPercentilesSeries({ concat: key }),
];
}
/**
* @param {Object} args
* @param {ChartableVecId & VecIdAverageBase & VecIdSumBase & TotalVecIdBase & VecIdMinBase & VecIdMaxBase & VecId90pBase & VecId75pBase & VecIdMedianBase & VecId25pBase & VecId10pBase} args.key
@@ -280,9 +291,7 @@ function createPartialOptions(colors) {
key,
name,
}),
createAverageSeries({ concat: key }),
...createSumTotalSeries({ concat: key }),
...createMinMaxPercentilesSeries({ concat: key }),
...createAverageSumTotalMinMaxPercentilesSeries(key),
];
}
@@ -363,17 +372,10 @@ function createPartialOptions(colors) {
{
name: "Count",
title: "Transaction Count",
bottom: [
createBaseSeries({
key: "tx-count",
name: "Count",
}),
createAverageSeries({ concat: "tx-count" }),
...createSumTotalSeries({ concat: "tx-count" }),
...createMinMaxPercentilesSeries({
concat: "tx-count",
}),
],
bottom: createBaseAverageSumTotalMinMaxPercentilesSeries({
key: "tx-count",
name: "Count",
}),
},
{
name: "Subsidy",
@@ -415,9 +417,9 @@ function createPartialOptions(colors) {
name: "Fee",
title: "Transaction Fee",
bottom: [
createAverageSeries({ concat: "fee" }),
...createSumTotalSeries({ concat: "fee" }),
...createMinMaxPercentilesSeries({ concat: "fee" }),
...createAverageSumTotalMinMaxPercentilesSeries("fee"),
...createAverageSumTotalMinMaxPercentilesSeries("fee-in-btc"),
...createAverageSumTotalMinMaxPercentilesSeries("fee-in-usd"),
],
},
{
@@ -701,9 +703,9 @@ export function initOptions({
} else if (key.includes("-size")) {
unit = "Megabytes";
} else if (key.includes("weight")) {
unit = "Weight Units";
unit = "WU";
} else if (key.includes("vbytes") || key.includes("vsize")) {
unit = "Virtual Bytes";
unit = "vB";
} else if (key.match(/v[1-3]/g)) {
unit = "Version";
} else {