mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-08-04 22:53:05 -07:00
137 lines
3.7 KiB
JavaScript
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)),
|
|
};
|
|
}
|