Files
brk/website/scripts/options/models/bedrock.js
T
2026-07-29 10:50:14 +02:00

137 lines
3.7 KiB
JavaScript

import { brk } from "../../utils/client.js";
import { colors } from "../../utils/colors.js";
import { Unit } from "../../utils/units.js";
import { line } from "../series.js";
const FLOOR_PERCENTILES = /** @type {const} */ ([
{ key: "pct95", name: "P95" },
{ key: "pct98", name: "P98" },
{ key: "pct99", name: "P99" },
{ key: "pct995", name: "P99.5" },
{ key: "pct999", name: "P99.9" },
]);
const LEVEL_PERCENTILES = /** @type {const} */ ([
{ key: "pct10", name: "P10" },
{ key: "pct20", name: "P20" },
{ key: "pct30", name: "P30" },
{ key: "pct40", name: "P40" },
{ key: "pct50", name: "P50" },
{ key: "pct60", name: "P60" },
{ key: "pct70", name: "P70" },
{ key: "pct80", name: "P80" },
{ key: "pct90", name: "P90" },
]);
/**
* @typedef {Object} BedrockMode
* @property {string} name
* @property {AnySeriesPattern} inLoss
* @property {{
* floor: Record<string, AnySeriesPattern>,
* level: Record<string, AnySeriesPattern>,
* lossThreshold: Record<string, AnySeriesPattern>,
* }} tree
*/
/**
* @param {BedrockMode} mode
* @param {AnySeriesPattern} ath
* @returns {PartialChartOption}
*/
function modeChart(mode, ath) {
return {
name: mode.name,
title: `Bitcoin Bedrock Model: ${mode.name}`,
top: [
...FLOOR_PERCENTILES.map((percentile, index) =>
line({
series: mode.tree.floor[percentile.key],
name: percentile.name,
color: colors.bedrock.percentiles[index],
unit: Unit.usd,
}),
),
...LEVEL_PERCENTILES.map((percentile, index) =>
line({
series: mode.tree.level[percentile.key],
name: `L${percentile.name.slice(1)}`,
color: colors.bedrock.levels[index],
unit: Unit.usd,
style: 1,
}),
),
line({
series: ath,
name: "L100",
color: colors.bedrock.levels[9],
unit: Unit.usd,
style: 1,
}),
],
bottom: [
line({
series: mode.inLoss,
name: "Loss",
color: colors.default,
defaultActive: false,
unit: Unit.ratio,
}),
...FLOOR_PERCENTILES.map((percentile, index) =>
line({
series: mode.tree.lossThreshold[percentile.key],
name: percentile.name,
color: colors.bedrock.percentiles[index],
defaultActive: false,
unit: Unit.ratio,
}),
),
],
};
}
/**
* Create Bedrock model section.
* @returns {PartialOptionsGroup}
*/
export function createBedrockSection() {
const { bedrock, market, cohorts, cointime, coinflow } = brk.series;
const horizonModes = /** @type {const} */ ([
{ key: "coinflow8y", horizon: "_8y", name: "Coinflow 8Y" },
{ key: "coinflow4y", horizon: "_4y", name: "Coinflow 4Y" },
{ key: "coinflow2y", horizon: "_2y", name: "Coinflow 2Y" },
{ key: "coinflow1y", horizon: "_1y", name: "Coinflow 1Y" },
{ key: "coinflow6m", horizon: "_6m", name: "Coinflow 6M" },
{ key: "coinflow3m", horizon: "_3m", name: "Coinflow 3M" },
{ key: "coinflow1m", horizon: "_1m", name: "Coinflow 1M" },
]).map((mode) => ({
name: mode.name,
tree: bedrock[mode.key],
inLoss: coinflow.horizon[mode.horizon].supply.inLoss.share,
}));
const modes = /** @type {readonly BedrockMode[]} */ ([
{
name: "Raw",
tree: bedrock.raw,
inLoss: cohorts.utxo.all.supply.inLoss.share.ratio,
},
{
name: "Cointime",
tree: bedrock.cointime,
inLoss: cointime.supply.active.inLoss.share,
},
{
name: "Coinflow",
tree: bedrock.coinflow,
inLoss: coinflow.supply.mobile.inLoss.share,
},
...horizonModes,
]);
return {
name: "Bedrock",
tree: modes.map((mode) => modeChart(mode, market.ath.high.usd)),
};
}